喫茶XRAYトップページ

[スレッド全体
]

[7327] 無題返信 削除
2014/3/10 (月) 23:56:16 snail
こんにちは、また教えて下さい。

(マスターなら知っていると思ったのですが、毎回ご指定
するのも悪いと思って)某掲示板で質問しようとしたところプロキシ経由では
ないにもかかわらず経由は駄目と断られてしまいました。 (;_;)

やりたいことは
自作アプリのグリッドに表示されている文字を文字の色を指定して
クリップボード経由でEXCELに貼り付けしたい。

例えば Clipboard.SetTextBuf を使えば文字列は簡単に
クリップボードにコピーできるけど当然色指定ができません。

一応「823_貼り付け操作可否のチェック ( クリップボードの監視 ) 」
などの記事も読ませていただきましたが、EXCELに持って行くと
テキストとしてしか認識できませんでした。

ヒントだけでも良いのでお願いします。


[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.


[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