コミュニティでの活動の履歴として、自身(Orator/魔界の仮面弁士)が掲示板・Mailing List・Newsgroup等へ発言した内容の中で、再利用できそうな物を拾い出して、掲載しています。

[.NET]CodeDOMで多次元配列の作成 / 2008年02月06日(水)

CodeDOM で『Dim Test(3, 2) As Integer』のような宣言を行おうにも、CodeArrayCreateExpression クラスは 1 次元配列しか作成できない…という話があったので、Array.CreateInstance を使った回避コードを作ってみました。


[02/06/2008]Programming Library(VB初心者掲示板)

Dim ArrayName As String = "Test"
Dim ArrayMaxIndex1 As Integer = 3
Dim ArrayMaxIndex2 As Integer = 2

Dim arrayInstance As New CodeMethodInvokeExpression( _
	New CodeTypeReferenceExpression(GetType(Array)), "CreateInstance", _
	New CodeTypeOfExpression(New CodeTypeReference(GetType(Integer))), _
	New CodePrimitiveExpression(ArrayMaxIndex1 + 1), _
	New CodePrimitiveExpression(ArrayMaxIndex2 + 1))

Dim variable As New CodeVariableDeclarationStatement( _
	GetType(Integer(,)), ArrayName, _
	New CodeCastExpression(GetType(Integer(,)), arrayInstance))

Dim statements As New CodeStatementCollection()
statements.Add(New CodeCommentStatement(String.Format("配列{0}の宣言", ArrayName)))
statements.Add(variable)

Using sw As New StringWriter()
	For Each language As String In "C#,VisualBasic,JScript,VJ#,C++".Split(",")
		Dim provider As CodeDomProvider = Nothing
		Try
			provider = CodeDomProvider.CreateProvider(language)
			If Not provider.Supports(GeneratorSupport.MultidimensionalArrays) Then
				sw.WriteLine("★{0} は多次元配列をサポートしていません。", language)
			End If
			sw.WriteLine("☆{0} として生成されたコード", language)
		Catch ex As Exception
			sw.WriteLine("★{0} のコードは生成できません。", language)
			sw.WriteLine()
			Continue For
		End Try
		For Each s As CodeStatement In statements
			provider.GenerateCodeFromStatement(s, sw, Nothing)
		Next
		sw.WriteLine()
	Next

	Dim GeneratedSource As String = sw.ToString()
	Clipboard.SetText(GeneratedSource)
	TextBox1.Text = GeneratedSource
End Using
 
 続きを読む...  
Posted at 22:43 / .NET / この記事のURL
コメント(0)
日本語版 Visual Studio 2008 登場! / 2007年12月14日(金)
Visual Studio 2008 日本語版の開発が完了。2 月より販売を開始

ついに、待望の VS2008 日本語版 の登場です。

パッケージ販売は 2008年2月8日からのようですが、MSDN Subscription の契約レベル次第では、既にダウンロードにて入手可能です。(約 4.5GB です。エディションによって異なりますが)

なお、来週18日には、無償版の Visual Studio 2008 Express Edition 日本語版もダウンロード可能になるとのことです。
 
 続きを読む...  
Posted at 14:24 / .NET / この記事のURL
コメント(0)
[VBA] Long 型同士の乗算がエラーにならない理由 / 2007年12月09日(日)

田中亨さんのExcel 2007 blogに、Excel 2007 に関する、以下のような実験コードがありました。

次のようなコードもオーバーフローします。
Sub Sample1()
    Dim n
    n = Rows.Count * Columns.Count
    MsgBox n
End Sub
なぜか次のように明示的にWorksheetオブジェクトを指定してやると、全行数×全列数の計算結果は取得できるようです。
Sub Sample1()
    Dim n
    n = Worksheets(1).Rows.Count * Worksheets(1).Columns.Count
    MsgBox n
End Sub

前者がエラーになる理由は明確ですね。これはつまり、Excel 2007 では、
 Rows.Count は、1,048,576 (Long 型)を返す。
 Columns.Count は、16,384 (Long 型)を返す。
 それらを乗算した結果は 17,179,869,184 となる。
 結果、Long の上限値 2,147,483,647 を上回ってしまう。
というものです。


では、何故後者がエラーにならないのかというと、Rows プロパティ以下がレイトバインドのコードであるため、Count プロパティの戻り値がLong 型ではなく、(内部Longの)Variant型として処理されていたためです。実は下記のように、いずれか一方が Variant 型であれば、オーバーフローにはなりません。

n = CVar(Rows.Count) * Columns.Count

これは何故かというと、「内部処理形式 Long の Variant 型」に対する乗算は、Long の精度を超えた場合、自動的に内部処理形式 Double の Variant 型」に拡張される…という仕様が存在しているためです。


この Variant に対する演算については、ヘルプの「* 演算子」の項にも書かれているのですが、よく読まないと見落としてしまうでしょうね。

 
   
Posted at 21:05 / Visual Basic / この記事のURL
コメント(0)
Windows Vista: ソフトウェア ビジネス / 2007年11月05日(月)
Windows Vista デベロッパー センター: ソフトウェア ビジネス
というサイトにおいて、6記事中 4 記事がデッドリンクになっていました。


ここで紹介されているものは、いずれも英語の記事だと書いてあるのですが、
調べてみると、その中のいくつかは既に日本語訳が登場している様子。勿体無い。

一応フィードバックはしておいたので、きちんとメンテナンスされる事を期待しつつ。
下記に、正しいと思われるリンク先を紹介しておきます。

(DeadLink #1)「ソフトウェア ビジネスについてのコラム (英語)
→「透明性に対する見解 (日本語)

(DeadLink #2)「.NET のビジネス バリュー (英語)
→ 「.NET in the Real World - The Business Value of .NET (英語)

(DeadLink #3)「Windows カタログに記載されるために (英語)
→ 「Windows カタログへの登録方法 (日本語)

(DeadLink #4) 「ソフトウェア用 Windows ロゴ プログラム (英語)
→「Designed for Windows - Windows Logo Program(日本語)」
 
   
Posted at 15:11 / 雑記 / この記事のURL
コメント(1)
Windows Vista ユーザー エクスペリエンス / 2007年11月03日(土)
Windows Vista ユーザー エクスペリエンス
という記事中にある
『Windows Vista UX Guidelines』(暫定版) のダウンロード (英語)
がデッドリンクになっている様子。

正しいリンク先は、多分、
Windows Vista User Experience Guidelines (Downdload Center)
Windows Vista User Experience Guidelines (MSDN)
あたりだと思うのだけど…暫定版のまま、放置されているのかな?

# 一応、フィードバックはしておいたけれども。
 
   
Posted at 17:40 / 雑記 / この記事のURL
コメント(0)
[ACE 12.0] メモ型フィールドの動作について / 2007年06月05日(火)

以前、[Jet 4.0] メモ型フィールドの最大長について という記事の中で、メモ型フィールドの最大値について書きましたので、あらためて Access 2007 バージョンで再実験してみました。


最初に実験結果から書くと、『最大で、536,870,911 文字を登録できる』ようです。

これは VB6 から ADO 2.8 + Microsoft.ACE.OLEDB.12.0 を用いて、AppendChunk を繰り返し呼び出して実験した結果です。

あれ。Jet 4.0 の時は、536,870,910 文字という結果だったような…?


最大長までデータを追加した後、ADO 2.8 の「ADODB.Field オブジェクトの ActualSize プロパティ」や、DAO 12.0 の「DAO.Field2 オブジェクトの FieldSize プロパティ」で再測定してみると、 1,073,741,822 バイトという値を返してきました。

1文字を2バイトとして換算すると、確かに一致していますね。


ただし、この FieldSize で得た値を、GetChunk メソッドに対して使う際には注意が必要です。

ヘルプでは、引数に指定する値は「バイト数」と書かれていますが、実際には、メモ型フィールドに対しては「文字数」として働くようですので…。


Dim RS As DAO.Recordset2
Set RS = DB.OpenRecordset(TableName)
If Not RS.EOF Then
    Dim F As DAO.Field2
    Set F = RS.Fields(FieldName)

    '「1073741822」と返された
    Debug.Print F.FieldSize

    Dim v As Variant
    v = F.GetChunk(600000000, 100)
    '「0」と返された
    Debug.Print LenB(v)

    v = F.GetChunk(500000000, 100)
    '「200」と返された
    Debug.Print LenB(v)
End If
RS.Close
 
   
Posted at 19:46 / Jet/Access / この記事のURL
コメント(0)
[.NET]DateTimePickerの最大値に関する問題点 / 2007年05月10日(木)

DateTimePicker クラス に指定できる最大の日付値は、MaxDate プロパティで変更可能です。
そして、MaxDate プロパティに指定できる最大値は、MaximumDateTime フィールドの値です。


しかし、ここには幾つかの問題が存在しているようです。


SDK を見てみると、DateTimePicker.MaxDateTime フィールド について、
日付の最大値は 12/31/9998 23:59:59 に設定されます。
と記されています。9999 年ではないようですね。


では実際に、VB2005 を使って、その日付を指定してみるとどうなるでしょう。

なんと、最大値が設定される事はなく、かわりに ArgumentOutOfRangeException 例外が発生します。

DateTimePicker1.MaxDate = #12/31/9998 23:59:59#

エラーメッセージを見ると、本当の最大値は、9998/12/31 00:00:00.0000000 とあります。
実際、メッセージにある日付を指定してみると、今度は無事に設定できます。

DateTimePicker1.MaxDate = #12/31/9998 00:00:00#  'OK

どうやら、ドキュメントの記述が間違っているようですね。


さて。

時刻部の微妙な問題はあれど、最大値が9998年12月31日ちょうど、という事はわかりました。


となると、日付型の最大値である、9999/12/31 23:59:59.9999999 は設定できないはずです。
こちらも実験してみましょう。


Dim dt As Date '= DateTimePicker.MaximumDateTime
dt = Date.MaxValue
DateTimePicker1.MaxDate = dt            'OK
DateTimePicker1.MaxDate = DateTime.Now  'OK
DateTimePicker1.MaxDate = dt            '例外


最初の 1 回だけ、DateTime.MaxValue が設定できてしまいましたが、これはおかしいですね。
本来であれば設定できない値のはずです。


しかも、一度別の値にしてから再設定すると、今度はエラーが発生するのです。




調べてみると、どうやら MaxDate プロパティの内部的な初期値が、本来設定すべき DateTimePicker.MaximumDateTime という値ではなく、DateTime.MaxValue になってしまっているために起こる現象のようです。

最初の一回目は、「初期値と同じ値を入れたので、内部値が変化せず、エラーにならなかった」わけですね。

 
   
Posted at 22:06 / .NET / この記事のURL
コメント(2)
IEの既定のエンコード指定 / 2007年04月26日(木)
最近 うちの Internet Explorer (WinXP) が不調です。
幾つかのサイトが文字化けしたり、行間が妙に開いてしまうという状態。


どうも先日、Windows Update からKB927489のJIS2004 対応フォントを入れたあたりから、おかしくなったような気がします。(KB927489 が原因と言っているわけでは無いです。念のため。)

というのも、KB927489 は(悪評通りに)気持ち悪かったので即座に消そうとしたのですが、何故か[プログラムの追加と削除]で[更新プログラム]をチェックしても、KB927489 が一覧に出てこなかったのでアンインストールできなかったのです。なんでだー。

仕方がないので、
%Windir%\$NtUninstallKB927489$\spuninst\spuninst.exe /u /z
のコマンドを使って、手動で消しました。
spuninst.exe 使うのは初めてなので、おっかなびっくり。

まぁ、それでフォント自体は元に戻ったのですが…IEの表示は崩れてる、という次第。

Charset 等がきちんと指定されているサイトなら問題無いのですが、そうでないサイトは、既定の文字コードが常に UTF-8 になってしまうという。まぁ、毎回右クリックして[エンコード]を変更すれば、文字化けせずに表示されるのですけれども、面倒な状況になったもんです。


そして後日。ふと、レジストリで IE 関連のキーを覗いてみたところ:
HKCU\Software\Microsoft\Internet Explorer\International\Default_CodePage
という怪しいエントリを発見!
バイナリ値で、e9 fd 00 00 と書かれています。

関数電卓をたたき、FDE9 を10進数変換したところ、その値は 65001。
65001 といえば、UTF-8 のコードページ値です。もしかしてコレか?

試しに、Shift_JIS を指定してみたらどうなるだろう? (ドキドキ
Shift_JIS は 932 だから… 0x3a4。
つまり、a4 03 00 00 というバイナリを指定すれば良いのかな。

レジストリを書き換えて、IE を開くと――やった! 表示が直ってる!
試しに、e4 04 00 00 にしたら、既定のエンコードが"西ヨーロッパ"に。ビンゴっ!!


念のため、他の人のレジストリを除いてみると。
あれ? Default_CodePage のエントリ自体無いぞ。

なんだ、削除するだけで良かったのか……。
 
   
Posted at 13:11 / 雑記 / この記事のURL
コメント(4)
[DAO]新バージョンの違いに関する考察 / 2007年03月17日(土)
ようやく Office 2007 を入れたので、今更ながらに Jet 関連を調査。
いつの間にか、DAOのバージョンが大幅に上がっている事に吃驚。


DAO 3.5 は、Access 97 で使われていて。
それ以降は、DAO 3.6 が Access 2000, 2002, 2003 と長らく使われていたのに。
それが Access 2007 では突然、DAO 12.0 となっている、と。

そもそも、Microsoft Jet (Joint-Engine Technology) Database Engine 自体が、その後方互換たる ACE (Access Database Engine) に変更されている様子。


とりあえず、表面的な部分だけ見れば、
 Set engine = CreateObject("DAO.DBEngine.35") 'JET 3.5x
 Set engine = CreateObject("DAO.DBEngine.36") 'JET 3.60
 Set engine = CreateObject("DAO.DBEngine.120") 'ACE 12.0
とか、
 Cn.Provider = "Microsoft.Jet.OLEDB.3.51" 'JET 3.5x
 Cn.Provider = "Microsoft.Jet.OLEDB.4.0" 'JET 3.60
 Cn.Provider = "Microsoft.ACE.OLEDB.12.0" 'ACE 12.0
とか、
 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\3.5
 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0
 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\12.0\Access Connectivity Engine
という形で切り替えれば済むとは思うのだけれども、チューニング設定のためには、幾つか追調査の余地がありそう。


たとえば、レジストリにある Engines エントリ。

\Jet\4.0\Engines キーには、[Jet 2.x]、[Jet 3.x]、[Jet 4.0] のエントリが並んでいるのに、12.0 の方は、[Jet 2.x]、[Jet 3.x] のエントリが残っているのに、何故か [Jet 4.0] のエントリが用意されていない様子。([ACE] はあるのだけれども)

「もしや、ACE エントリが Jet 4.0 の役目を持っているのか?」とも一瞬思ったのだけれども、その既定値を見ると、実は Jet 4.0 のそれとは微妙に異なっていた(※)ので、実験を重ねないと何とも言い難いところ。

そうすると、DAO 12.0 で Jet 4.0 データベースを開くときの設定は、どこに書けばよいのだろう…。
まぁ、そういう時は DAO 3.6 を使い続ければ良いのだろうけれども。


具体的には、LV ページの再利用フラグ。JET 4.0 までは「オフ」がデフォルトだったのに、12.0 のデフォルトは「オン」にされている様子。
 
   
Posted at 18:37 / Jet/Access / この記事のURL
コメント(0)
[Jet]古い日付値を扱う場合の注意点 / 2006年12月03日(日)
table1
id date1 date2
1 1899/12/31 10:00:00 1899/12/31 20:00:00
2 1899/12/01 10:00:00 1899/12/01 20:00:00

上記のようなデータに対し、下記のクエリを発行してみます。

SELECT * FROM table1 WHERE date1 < date2

すると、id=1 はヒットするが、id=2 はヒットしないという、不都合のある状況になります。


これは、Jetの日付型の特性によるものです。

Jet の日付型は、「1899/12/30 00:00:00 からの経過日数」を、『倍精度浮動小数点型(Double)』で管理したものとなっています。

日付部の範囲は 100年1月1日〜9999年12月31日で、内部値の整数部は、 -657,434 〜 2,958,465 という範囲の値となります。

時刻部に関しては、たとえば 18:00:00 ならば、1日の 4分の3 として、0.750 という値をとります。06:00:00 なら、0.250 です。

そして、ここからが問題となる箇所なのですが…。

この時刻部というのは、内部値の絶対値に対する小数部として表されるため、負数となる範囲では、同一日の時刻判定に不都合が生じ、今回の例のような問題が発生します。

言葉で書くと分かりにくいので、表にしてみますと、1899/12/30 以上と未満とで、時刻部の方向が逆転している事がわかるかと思います。

+1.50……1899/12/31 12:00:00
+1.00……1899/12/31 00:00:00
+0.75……1899/12/30 18:00:00
+0.50……1899/12/30 12:00:00
+0.25……1899/12/30 06:00:00
0.00……1899/12/30 00:00:00
-0.25……(未使用領域)
-0.50……(未使用領域)
-0.75……(未使用領域)
-1.00……1899/12/29 00:00:00
-1.25……1899/12/29 06:00:00
-1.50……1899/12/29 12:00:00
-1.75……1899/12/29 18:00:00
-2.00……1899/12/28 00:00:00
-2.50……1899/12/28 12:00:00

もっとも、こんな古い日付値を(それも時刻部も含めた形で)保持する事は、稀だと思いますので、実運用上は、さほど支障は無いと思います。

とはいえ、この現象は、Jetのみならず、VBA/VB6/VBScript にも言える事なので、注意しておいた方が良いでしょうね。(VB.NETのDate型は問題なし)。

 
   
Posted at 02:43 / Jet/Access / この記事のURL
コメント(1)
P R

Microsoft Most Valuable Professional, Visual Developer - Visual BasicMSMVP for Visual Basic

 前へ | 次へ  
 
Global Media Online INC.