喫茶XRAYトップページ

[スレッド全体
]

[7365] 文字の色を指定してEXCELにコピー返信 削除
2014/3/16 (日) 16:04:57 Mr.XRAY
このスレッドを読んでいる方に,誤解のないように,お断りしておきます.
[7361] で,一応クリップボード経由で,エクセルで [貼り付け] をすると,
文字の色等,書式付きで貼り付けできるようにしてみました.

これは,あくまでも,エクセル側で [貼り付け] 操作をした時に,
書式も反映させるためです.
エクセルの,特定のセルに,書式付きで文字列を代入したいのであれば,
エクセルのオブジェクトを操作すればできます.


[7471] Re:文字の色を指定してEXCELにコピー返信 削除
2014/4/10 (木) 10:00:16 snail
▼ Mr.XRAYさん

恐ろしや、あっという間に1ヶ月たちました。

> これは,あくまでも,エクセル側で [貼り付け] 操作をした時に,
> 書式も反映させるためです.


マスターの例では書かれているとおりで、形式が TEXT のため
LibreOffice では正しく表示できませんでした。
EXCEL はなんと HTML ヘッダが無くても表示してしまいます。
HTMLフォーマットにするため色々なところからパクって修正したソースを
貼り付けておきます。
想定した使用例は StringGrid の内容をクリップボードに貼り付けます。
なお LibreOffice で実行するとタイトル行にゴミが付きます。
これは LibreOffice のバグ?と思います。

あとクリップボードの確認には「クリップ見え窓」というソフトを利用させて
いただきました。作者の方に感謝します。
http://www.officedaytime.com/clipmm/

注意:
変数名に「日本語」が入っているため XE2 以上でないとコンパイルできません。

unit Unit7;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, EditGrid, Vcl.Buttons,
  Vcl.StdCtrls, Vcl.ExtCtrls, Vcl.Clipbrd, Vcl.DBGrids;

type
  TClipboardAccess = class( TClipboard )
  end;

procedure Cs_StrCellClipHtmlCopy( ArgGrid : TStringGrid; ArgRowEnd : Integer = (-1); ArgCkCol : Integer = (-1) );

implementation

//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
// http://stackoverflow.com/questions/22617990/how-to-create-picture-and-html-formats-all-together-on-the-clipboard
//-----------------------------------------------------------------------
//         HTML形式の ClipBord コピー用ヘッダ作成
//-----------------------------------------------------------------------
procedure Cs_StrCellClipHtmlCopy( ArgGrid : TStringGrid; ArgRowEnd : Integer = (-1); ArgCkCol : Integer = (-1) );
const
  CnsHtmlFrom : String = (            // HTML開始
    '<html>'
  );
  CnsHtmlTo : String = (              // HTML終了
    '</html>'
  );
  CnsHeadFrom : String = (            // ヘッダ開始
    '<THEAD>'
  );
  CnsEtc : String = (                 // おまじない
    '<!--StartFragment-->'
   + ' <table border="1">'
  );
  CnsHeadTo : String = (              // ヘッダ終了
    '</THEAD>'
  );
  CnsBodyFrom : String = (            // 明細部、ボディ開始
    '<BODY>'
  );
  CnsBodyTo : String = (              // 明細部、ボディ終了
    '</BODY>'
 ) ;
  CnsTableFrom : String = (           // 表=テーブル、開始
    '<tr>'
  );
  CnsTableTo : String = (             // 表=テーブル、終了
    '</tr>'
  );
  CnsCellLeft : String = (            // セル、文字横位置、左寄せ
    '<td align="left">'
  );
  CnsCellCenter : String = (          // セル、文字横位置、中央
    '<td align="center">'
  );
  CnsCellRight : String = (           // セル、文字横位置、右寄せ
    '<td align="right">'
  );
  CnsCellTo : String = (              // セル、指定終了
    '</td>'
  );
  CnsCellFontRedFrom : String = (     // セル、Font色=赤
    '<font color="#ff0000">'
  );
  CnsCellFontRedTo : String = (       // セル、Font指定終了
    '</font>'
  );

  function FormatHTMLClipboardHeader( ArgHTMLText : UTF8String ): AnsiString;
  const
    CrLf = #13#10;
  begin
    Result := 'Version:0.9' + CrLf;
    Result := Result + 'StartHTML:-1' + CrLf;
    Result := Result + 'EndHTML:-1' + CrLf;
    Result := Result + 'StartFragment:000081' + CrLf;
    Result := Result + 'EndFragment:°°°°°°' + CrLf;
    Result := Result + ArgHTMLText + CrLf;
    Result := StringReplace( Result, '°°°°°°', Format('%.6d', [ Length( Result ) ]), [] );
  end;
var
  CF_HTML: UINT;
  SwtFind : Boolean;
  WHtmlStr : UTF8String;
  WCurrency : Currency;
  WCol, WRow, WSize, WCount : Integer;
  WStr, WStrWk, WHeadStr, W文字位置 : String;
begin
  if ( ArgGrid is TCustomGrid ) = False then exit;

  CF_HTML  := RegisterClipboardFormat( 'HTML Format' );


           //-------------------------------------
           // ClipBord へ渡すデータ作成開始
           //-------------------------------------
  WStr := '';
  WStr := WStr + CnsHtmlFrom;        // HTML開始
           //-------------------------------------
           // ClipBord へ渡すデータ、ヘッダ
           //-------------------------------------
  WStr := WStr + CnsHeadFrom;        // ヘッダ開始
  WStr := WStr + CnsEtc;             // おまじない
  for WRow := 0 to ( ArgGrid.FixedRows - 1 ) do
  begin
    WStr := WStr + CnsTableFrom;       // 表=テーブル、開始
    for WCol := 0 to ( ArgGrid.ColCount - 1 ) do
    begin
      W文字位置 := CnsCellLeft;

      if WCol = 1 then
        W文字位置 := CnsCellCenter
       else if WCol = 2 then
        W文字位置 := CnsCellRight;
      WStr := WStr + W文字位置 + UTF8String( ArgGrid.Cells[ WCol, WRow ] ) + CnsCellTo; // セル、指定終了
    end;
    WStr := WStr + CnsTableTo;         // 表=テーブル、終了
  end;
  WStr := WStr + CnsHeadTo;          // ヘッダ終了

           //---------------------------------------
           // ClipBord へ渡すデータ、ボディ(明細)部
           //---------------------------------------
  if ArgGrid.ColCount <= ArgCkCol then  // 列値 <> NULL 確認だが、確認する列が実際の列数より大きい
    ArgCkCol := (-1);
  WCount := 0;
  WStr   := WStr + CnsBodyFrom;         // 明細部、ボディ開始
  for WRow := ArgGrid.FixedRows to ( ArgGrid.RowCount - 1 ) do
  begin
    if 0 <= ArgCkCol then  // 列値 <> NULL 確認
    begin
      if ArgGrid.Cells[ ArgCkCol, WRow ] = '' then
        continue;
    end;
    if 0 < ArgRowEnd then
    begin
      Inc( WCount );
      if ArgRowEnd < WCount then break;
    end
     else if ArgRowEnd = (-1) then  // 全列空白はSKIP
    begin
      SwtFind := False;
      for WCol := ArgGrid.FixedCols to ( ArgGrid.ColCount - 1 ) do
        if ArgGrid.Cells[ WCol, WRow ] <> '' then
        begin
          SwtFind := True;
          break;
        end;
      if SwtFind = False then continue;
      Inc( WCount );
    end;
    WStr := WStr + CnsTableFrom;       // 表=テーブル、開始
    for WCol := 0 to ( ArgGrid.ColCount - 1 ) do
    begin
      W文字位置 := CnsCellLeft;

      if ( ArgGrid is TEditGrid ) = True then
      begin
        if WCol = 1 then
          W文字位置 := CnsCellCenter
         else if WCol = 2 then
          W文字位置 := CnsCellRight;
{/////////////////  TDBGrid の場合はこんな感じで文字表示位置を確認
        if TDBGrid( ArgGrid ).Fields[ WCol ].Alignment = taCenter then
          W文字位置 := CnsCellCenter
         else if TDBGrid( ArgGrid ).Fields[ WCol ].Alignment = taRightJustify then
          W文字位置 := CnsCellRight;
/////}
      end;
      WStrWk := ArgGrid.Cells[ WCol, WRow ];
      if W文字位置 = CnsCellRight then  // 右詰=マイナス数値の場合は赤色にする。
      begin
        WCurrency := StrToIntDef( WStrWk, 0 );  // ←整数以外 , . などがあると駄目
        if WCurrency < 0 then
          WStrWk := CnsCellFontRedFrom + WStrWk + CnsCellFontRedTo;  // セル、Font指定
      end;
      WStr := WStr + W文字位置 + UTF8String( WStrWk ) + CnsCellTo; // セル、指定終了
    end;
    WStr := WStr + CnsTableTo;         // 表=テーブル、終了
  end;
  WStr := WStr + CnsBodyTo;           // 明細部、ボディ終了
  WStr := WStr + CnsHtmlTo;          // HTML終了

  Clipboard.Open;
  try
    WHtmlStr := FormatHTMLClipboardHeader( WStr );
    WSize   := Length( AnsiString( WHtmlStr ) );
    TClipboardAccess( Clipboard).SetBuffer( CF_HTML, PAnsiChar( WHtmlStr )^, WSize + 1);
    TClipboardAccess( Clipboard).SetBuffer( CF_TEXT, PAnsiChar( WHtmlStr )^, WSize + 1);
  finally
    Clipboard.Close;
  end;
end;

end.


[7472] Re2:文字の色を指定してEXCELにコピー返信 削除
2014/4/10 (木) 14:08:33 Mr.XRAY
▼ snailさん

> 恐ろしや、あっという間に1ヶ月たちました。

「更新矢のごとし...」ですね (^^; というほどの時間ではない ?
しつこくやっていますね.プログラマに必要な資質でしょう(笑)

> いただきました。作者の方に感謝します。
> http://www.officedaytime.com/clipmm/


こんなのがあるんですね.
snail さんが提示したコードは実際にやつていませんが,
なるほど,です.


[7474] Re3:文字の色を指定してEXCELにコピー返信 削除
2014/4/10 (木) 18:34:40 Mr.XRAY
> > いただきました。作者の方に感謝します。
> > http://www.officedaytime.com/clipmm/


ちょっと使ってみました.なるほど,ある意味では便利ですね.
確かに開発者用でしょう.
サンプルプログラム集の [823][04] の参考リンクに追加しておきました.


[7475] Re4:文字の色を指定してEXCELにコピー返信 削除
2014/4/10 (木) 19:16:08 snail
▼ Mr.XRAYさん
> サンプルプログラム集の [823][04] の参考リンクに追加しておきました.


>掲載 2011年01月16日  更新 2013年12月07日 Delphiサンプルプログラム集

まだ修正していないと思ったら、しっかり直っていましたね。

>しつこくやっていますね.プログラマに必要な資質でしょう(笑)

消費税対応&!!!!の2ヶ月でした。 (;_;)

やらなくてはいけない事が沢山あるけど、体力がありません。
そのくせ休日は遊びに行ってしまう。(‥;)




[7477] Re5:文字の色を指定してEXCELにコピー返信 削除
2014/4/10 (木) 20:14:49 Mr.XRAY
▼ snailさん

> まだ修正していないと思ったら、しっかり直っていましたね。

ハハハッ.誤字脱字とか,こまかいソースコードの修正は,
更新日時を変えていませんのです.スンません.


[7480] Re6:文字の色を指定してEXCELにコピー返信 削除
2014/4/11 (金) 08:23:54 Mr.XRAY
> ハハハッ.誤字脱字とか,こまかいソースコードの修正は,
> 更新日時を変えていませんのです.スンません.


更新日時より ZIP ファイルの日付が新しい場合
  ソースコード等の誤字脱字等の修正

更新日時の方が ZIP ファイルの日付より新しい場合
  記事の誤字脱字とか文章の修正等

ですね.


[7479] Re2:文字の色を指定してEXCELにコピー返信 削除
2014/4/11 (金) 07:41:31 Mr.XRAY
▼ snailさん
折角のコードですので,やってみました.
テストコードは以下です.
新規プロジェクトを作成し,TButton と TStringGrid を配置.
snail さんの以下の部分を変更

      if ( ArgGrid is TEditGrid ) = True then
        ↓
      if ( ArgGrid is TStringGrid ) = True then

動作確認は,Windows 7 U64(SP1) + Delphi XE5(UP2) Pro (ヘヘヘッ)
            + Excel 2010

この前に,snail さんのコード
//=============================================================================
//  フォーム生成時にテスト用データをStringGird1にセット
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  StringGrid1.DefaultDrawing := True;

  StringGrid1.ColCount        := 4;
  StringGrid1.FixedCols       := 1;
  StringGrid1.DefaultColWidth := 90;
  //ここまではオブジェクトインスペクタで設定してもよい

  //左端の列幅設定
  StringGrid1.ColWidths[0]    := 10;

  //テスト用の値をセット
  StringGrid1.Cells[1,0] := '調査番号';
  StringGrid1.Cells[2,0] := '都道府県';
  StringGrid1.Cells[3,0] := '結果値';

  //テスト用の値をセット
  StringGrid1.RowCount := 4;
  StringGrid1.Cells[1,1] := 'A-100';
  StringGrid1.Cells[1,2] := 'A-200';
  StringGrid1.Cells[1,3] := 'A-300';

  StringGrid1.Cells[2,1] := '東京都';
  StringGrid1.Cells[2,2] := '大阪府';
  StringGrid1.Cells[2,3] := '京都府';

  StringGrid1.Cells[3,1] := '500';
  StringGrid1.Cells[3,2] := '800';
  StringGrid1.Cells[3,3] := '300';
end;

//=============================================================================
//  StringGrid1のセルデータをクリップボードにコピー
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
  Cs_StrCellClipHtmlCopy(StringGrid1);
end;


  const
    CrLf = #13#10;

は sLineBreak 定数がありまね.
http://mrxray.on.coocan.jp/Delphi/plSamples/200_MemoReadSpeed.htm#05-03

TEditGrid って,これですか ?

http://www.csjpn.com/soft/ware4.html#TEditGrid



[7487] Re3:文字の色を指定してEXCELにコピー返信 削除
2014/4/14 (月) 20:27:55 snail
▼ Mr.XRAYさん

>   const
>     CrLf = #13#10;
>
> は sLineBreak 定数がありまね.
> http://mrxray.on.coocan.jp/Delphi/plSamples/200_MemoReadSpeed.htm#05-03


インターネット丸コピー、+勉強不足。
 
> TEditGrid って,これですか ?
>
> http://www.csjpn.com/soft/ware4.html#TEditGrid


そんなページが有ることも忘れていました。


[7489] Re4:文字の色を指定してEXCELにコピー返信 削除
2014/4/14 (月) 20:58:07 Mr.XRAY
▼ snailさん

> そんなページが有ることも忘れていました。

「忘却とは忘れ去ることなり。忘れ得ずして忘却を誓う心の悲しさよ」

放送時間帯は,銭湯の女風呂が空になる程ヒットしたラジオドラマ
「君の名は」の始まりのナレーションです.
http://www.youtube.com/watch?v=AWo6nvlWKIk

これを聞くと,戦時中のつらいことを思い出すのです.
あの頃,僕は二十歳だった,君は,19 ...
へえー,古関裕而の作曲なんだ.
1964 年の東京オリンピックの開会式の入場行進で使われたマーチの作曲者です.


[▼次のスレッド]
INCM/CMT
Cyclamen v3.82