Excel には、次の 2 つのフィールドがあります。
NumberFormat
NumberFormatLocal
NumberFormat は、米国標準では常にロケール不変の形式を取り、NumberFormatLocal は、設定されたロケールでの形式を想定しています。
例えば
Sub test()
Dim r As Range
Set r = ActiveWorkbook.ActiveSheet.Range("$A$1")
r.NumberFormat = "#,##0.00"
Set r = ActiveWorkbook.ActiveSheet.Range("$A$2")
r.NumberFormat = "#.##0,00"
Set r = ActiveWorkbook.ActiveSheet.Range("$A$3")
r.NumberFormatLocal = "#,##0.00"
Set r = ActiveWorkbook.ActiveSheet.Range("$A$4")
r.NumberFormatLocal = "#.##0,00"
End Sub
ドイツ語の設定 (10 進数 sep: および 1000 sep: .) を使用すると、$A$1 および $A$4 の正しい書式設定された数値が得られます。ウィンドウの地域設定を好きなように変更して試してみると、フォーマットが機能している場合はテストできます。
Delphi 5 を使用していて、次のように Excel を起動するコードがあると仮定します (そして、ComObj.pas にアクセスできます)。
var
oXL, oWB, oSheet : Variant;
LocaleId : Integer;
begin
oXL := CreateOleObject('Excel.Application');
oXL.Visible := True;
oWB := oXL.Workbooks.Add;
oSheet := oWB.ActiveSheet;
oSheet.Range['$A$1'].NumberFormatLocal := '#.##0,00';
oSheet.Range['$A$2'].NumberFormatLocal := '#,##0.00';
LocaleID:= DispCallLocaleID($0409);
try
oSheet.Range['$A$3'].NumberFormat := '#.##0,00';
oSheet.Range['$A$4'].NumberFormat := '#,##0.00';
finally
DispCallLocaleId( LocaleId);
end;
end;
デフォルトでは、すべての呼び出しは、ComObj.DispatchInvoke を呼び出す ComObj.VarDispInvoke を経由します。そこには、3 番目のパラメーターとして lcid を取得する Dispatch.Invoke への呼び出しがあります。これは 0 に設定されています。これへのコメントの最初のリンクに示されている手法を使用して、独自のユニットを作成し、ComObj からすべてのコードを独自のユニットにコピーする (または ComObj を直接変更する) ことができます。ユニットの初期化で VarDispProc 変数を設定することを忘れないでください。最後の部分はすべての場合に機能するとは限りません (おそらくモジュールの順序に依存します) が、コードで変数を設定できます。
VarDispProc := @VarDispInvoke;
ここで、VarDispInvoke を ComObj コピー モジュールのインターフェイス セクションに配置する必要があります。最初のリンクのコードは、上記の Delphi サンプルでは呼び出されていない別のメソッドを変更しているため、直接は機能しません。
また、numberformat 呼び出しのロケールを変更するだけで十分です (副作用を避けるため)。
上記の例と説明されている変更は、私のドイツ語の Excel の正解で機能します。変更または DispCallLocaleId への呼び出しがなければ、あなたが説明したのと同じ問題が発生します。