EXCELでバリアント配列を使ったセル色の設定

解決


いわた  2013-08-24 09:17:25  No: 45138

お世話になっております。

OLEでEXCELの操作を行いたいのですが、バリアント配列を使ったセル値のセットが
どうもうまくいきません。

下のコードでは、特定範囲のセルの色を偶数行と奇数行でピンクと黄色に塗り分けようとしているのですが、
すべて黄色になってしまいます。
ただ、セルの値(「AAA」or「BBB」)については、きちんと偶数行と奇数行で変えることが出来ています。

こうしないとダメ、という点があればご指摘いただけないでしょうか。

よろしくお願い致します。

var
  ExcelObj, WorkBook, WorkSheet:OleVariant;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ExcelObj  := CreateOleObject('Excel.Application');
  WorkBook  := ExcelObj.Workbooks.Add;
  WorkSheet := WorkBook.WorkSheets[1];
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  r, c:Integer;
  ValueArray, CellColorArray: OleVariant;
begin
  ValueArray     := VarArrayCreate([1, 9, 1, 5],VarVariant);
  CellColorArray := VarArrayCreate([1, 9, 1, 5],VarVariant);
  try
    for r := 1 to 9 do
    begin
      for c := 1 to 5 do
      begin
        //偶数行と奇数行で内容を変える
        if Odd(r) then
        begin
          ValueArray    [r, c] := 'AAA';
          CellColorArray[r, c] := 6;  //黄色
        end else
        begin
          ValueArray    [r, c] := 'BBB';
          CellColorArray[r, c] := 38; //ピンク
        end;
      end;
    end;

    WorkSheet.Range['A1:E9'].Value               := ValueArray;
    WorkSheet.Range['A1:E9'].Interior.ColorIndex := CellColorArray;
  finally
    VarClear(ValueArray);
    VarClear(CellColorArray);
  end;

  //EXCELを表示
  ExcelObj.Visible := True;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  ExcelObj.DisplayAlerts := false;
  ExcelObj.WorkBooks.Close;
  ExcelObj.Quit;
  ExcelObj := Unassigned;
end;


takana  2013-08-26 05:35:40  No: 45139

WorkSheet.Range['A1:E9'].Interior.ColorIndex := CellColorArray;
ColorIndexに配列を設定することはできないでしょう。
試してないけど、以下の内容でどうでしょうか?

    for r := 1 to 9 do
    begin
      for c := 1 to 5 do
      begin
        //偶数行と奇数行で内容を変える
        if Odd(r) then
        begin
          ValueArray    [r, c] := 'AAA';
          WorkSheet.Range['A1:E9'].Cells(r,c).Interior.ColorIndex := 6;  //黄色
          //あるいは()は[]かも
          WorkSheet.Range['A1:E9'].Cells[r,c].Interior.ColorIndex := 6;  //黄色
        end else
        begin
          ValueArray    [r, c] := 'BBB';
          WorkSheet.Range['A1:E9'].Cells(r,c).Interior.ColorIndex := 38; //ピンク
          //あるいは()は[]かも
          WorkSheet.Range['A1:E9'].Cells[r,c].Interior.ColorIndex := 38; //ピンク
        end;
      end;
    end;


いわた  2013-08-26 08:07:49  No: 45140

takanaさん、ご返信ありがとうございます。

ColorIndexに配列を設定することはできないんですね。
もともとセルの色塗りに関して、単純に1セル1セルにColorIndexをセットしていると
描画速度に問題が発生したため、配列が使えないかと試みていました。
なので配列が使えないことは残念ですが、「配列は使えない」ということが分かっただけでも有難いです。

何か別の方法がないか検討してみることにします。。

ありがとうございました。


Nov  2013-08-26 09:43:52  No: 45141

試してませんが、書式のコピーを使えば時間を短縮できるかも知れません。
コピーなので、少なくとも2行分は書式設定しないと使えませんが...

参考(VBAですが):http://www.happy2-island.com/excelsmile/smile03/capter00505.shtml


takana  2013-08-27 08:02:30  No: 45142

1セル1セルではなく
1行1行ごとにColorIndexをセットすれば、いくらか高速になります。

WorkSheet.Range['A1:E9'].Rows(r).Interior.ColorIndex := 6;

あるいは全体をいったんピンクにして
WorkSheet.Range['A1:E9'].Interior.ColorIndex := 38; //ピンク
後で偶数行?だけ再度黄色にするとさらに高速になるのでは?


いわた  2013-08-28 07:45:16  No: 45143

Novさん、takanaさん、ご返信ありがとうございます。

Novさん:
CopyとPastespecialの組み合わせで書式のコピーを行なうことで、
以前より速い描画が出来るようになりました。

takanaさん:
ありがとうございます。
同じ色なら行単位で一気に指定できるんですね。知りませんでした。

いただいた案をもとに、今回はどの案で進めるのがベストか試行錯誤してみたいと思います。
ありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加