お知らせ

電子会議

ライブラリ

パレット

Delphi FAQ検索

Delphi FAQ一覧

サンプル蔵





FDelphi FAQ
16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル

"EXCELからStringGridにデータをコピー"





  クリップボードにコピーしたエクセルのデータをStringGrid に貼り付けます。
通常は Clipboard.Astext として読み出してやれば間に合いますが、この方法で
は実数値データがエクセルの表示幅に合わせてカットされてしまう場合がありま
す。数値の精度を落とさずにコピーするために、クリップボードの内容をいった
んSYLK形式で読み出してから、StringGridの指定セルの位置に貼り付けます。

  SYLK形式でクリップボードを読み出す方法は MES(6) #30709でポン太さんが提
供された方法に依っています。


uses Windows,Grids,Clipbrd,SysUtils;
{--------------------------------------------------------
クリップボードのデータをSYLK形式経由でセルに書き込む。
---------------------------------------------------------}
procedure PasteFromClipboardToStringGridBySYLK(SGrid : TStringGrid);
const
  CRLF  = #13#10;
var
  H                 :THandle;
  P                 :PChar;
  Len               :Integer;
  S, Line, L2, Data :string;
  Row,Col,
  StartRow,StartCol,
  StartX,StartY     :integer;
begin
  {念のための初期化}
  Row    := -1;
  Col    := -1;
  StartX := -1;
  StartY := -1;
  {SYLK形式でクリップボードのデータを S に読み込む}
  Clipboard.Open;
  try
    H := GetClipboardData(CF_SYLK);
    if H<>0 then begin
      P := GlobalLock (H);
      GlobalUnlock(H);
      Len:=GlobalSize(H);
      SetLength(S,Len);
      StrPLCopy(PChar(S),P,Len);
    end;
  finally
    Clipboard.Close;
  end;
  {最初のセル位置を記録した行まで削除}
  while Length(S) > 0 do begin
    {1行受け取る}
    Line := Copy(S,1,Pos(CRLF,S)-1);
    {セル位置の記録を見つけたら読み出して終了}
    if (Length(Line)>0)   and (Line[1] in ['C','F']) and
       (Pos(';X',Line)>0) and (Pos(';Y',Line)>0) then begin
      L2 := Copy(Line,Pos(';X',Line)+2,Length(Line));
      if Pos(';',L2)>0 then L2 := Copy(L2,1,Pos(';',L2)-1);
      StartX := StrToInt(L2);
      L2 := Copy(Line,Pos(';Y',Line)+2,Length(Line));
      if Pos(';',L2)>0 then L2 := Copy(L2,1,Pos(';',L2)-1);
      StartY := StrToInt(L2);
      break;
    end;
    {見つからなかったら削除}
    Delete(S,1,Pos(CRLF,S)+1);
  end;

  {セル位置の記録が見つからなかったら終了する}
  if (StartX < 0) or (StartY < 0) then Exit;

  {グリッドの指定位置のセル座標をキープ}
  StartRow := SGrid.Selection.Top;
  StartCol := SGrid.Selection.Left;
  {データの読み出しと書き出し}
  while Length(S) > 0 do begin
    {1行受け取る}
    Line := Copy(S,1,Pos(CRLF,S)-1);
    {すでに読んだ行は削除}
    Delete(S,1,Pos(CRLF,S)+1);
    {有効な情報はCまたはFで始まる}
    if (Length(Line)>0) and
        ((Line[1] = 'C') or
         ((Line[1] = 'F') and ((Pos(';X',Line)>0) or
                               (Pos(';Y',Line)>0)))) then begin
      {X座標のデータがあれば Col を更新}
      if Pos(';X',Line) > 0 then begin
        L2 := Copy(Line,Pos(';X',Line)+2,Length(Line));
        if Pos(';',L2)>0 then L2 := Copy(L2,1,Pos(';',L2)-1);
        Col := StartCol - StartX + StrToInt(L2);
      end;
      {Y座標のデータがあれば Row を更新}
      if Pos(';Y',Line) > 0 then begin
        L2 := Copy(Line,Pos(';Y',Line)+2,Length(Line));
        if Pos(';',L2)>0 then L2 := Copy(L2,1,Pos(';',L2)-1);
          Row := StartRow - StartY + StrToInt(L2);
      end;
      {データがあるときには読み出してStringGridに書き込む}
      if (Pos(';K',Line) > 0) and (Row > 0) and (Col > 0) then begin
        Data := Copy(Line,Pos(';K',Line)+2,Length(Line));
        if Pos(';',Data) > 0 then
          Data := Copy(Data,1,Pos(';',Data)-1);
        if Data[1] = '"' then
          Data := Copy(Data,2,Length(Data)-2);
        SGrid.Cells[Col, Row] := Data;
      end;
    end;
  end;
end;


ひの


Original document by ひの            氏 ID:(GFD03044)


ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。

Copyright 1996-2002 Delphi Users' Forum