起步软件技术论坛-X3

 找回密码
 立即注册
搜索
查看: 382|回复: 10

【结贴】Excel进程

[复制链接]
发表于 2010-5-22 14:46:45 | 显示全部楼层 |阅读模式
看了http://bbs.justep.com/forum.php? ... 照6楼代码写的
现在发现创建的Excel进程需要在Business.exe退出后才释放,是这样吗?
如果不是这样,我再贴一下我的代码
回复

使用道具 举报

发表于 2010-5-22 21:56:35 | 显示全部楼层
不是的,应该是你有对象创建后 没释放的原因。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-5-24 09:04:53 | 显示全部楼层

请看看代码哪里写的不对,谢谢

{*******************************************************
    procedure:    GetPicFromExcel
    Describe:     读Excel指定Sheet、行、列内的图片
    Author:      
    Date:         2010-01-02
******************************************************* }
function TINFO_PROJECTDETAIL.GetPicFromExcel(AFileName: string; AJPG: TJPEGImage;
  ASheetIndex, ARowIndex, AColumnIndex:Integer): Boolean;
var
  objApplication, objWorkBooks: Object;
  dispatchApplication, dispatchWorkBooks, dispatchSourceWB: System.DispatchHelper;
  tmpCell, tmpSheet, tmpShapes, tmpShapeItem: System.DispatchHelper;
  left, top, height, width: Double;
  tmpLeft,tmpTop: Double;
  i, ShapeCount: Integer;   //图形个数
  lSourceBmp: Business.System.TBitmap;
  lTragetBmp: Business.System.TBitmap;
  //l1, l2, l3: TStream;
begin
  Result := False;
  objApplication := ComObj.CreateOleObject('Excel.Application');
  dispatchApplication := DispatchHelper.Create(objApplication);
  objWorkBooks := dispatchApplication.PropertyGet('WorkBooks',[]);
  dispatchWorkBooks := DispatchHelper.Create(objWorkBooks);
  try
    try
      //创建Excel对象并打开
      dispatchSourceWB := DispatchHelper.Create(dispatchWorkBooks.InvokeMethod('Open',[AFileName]));
      //获取指定单元格的左 上 宽 高
      tmpCell := DispatchHelper.Create(dispatchApplication.PropertyGet('cells', [ARowIndex, AColumnIndex]));
      left := SysUtils.StrToFloat(ObjectHelper.ToString(tmpCell.PropertyGet('left', [])));
      top := SysUtils.StrToFloat(ObjectHelper.ToString(tmpCell.PropertyGet('top', [])));
      width := SysUtils.StrToFloat(ObjectHelper.ToString(tmpCell.PropertyGet('width', [])));
      height := SysUtils.StrToFloat(ObjectHelper.ToString(tmpCell.PropertyGet('height', [])));
      //获取全部的格数
      tmpSheet := DispatchHelper.Create(dispatchApplication.PropertyGet('Sheets', [ASheetIndex]));
      tmpShapes := DispatchHelper.Create(tmpSheet.PropertyGet('Shapes', []));
      ShapeCount := SysUtils.StrToInt(ObjectHelper.ToString(tmpShapes.PropertyGet('Count', [])));
      for i := 1 to ShapeCount do
      begin
        tmpShapeItem := DispatchHelper.Create(tmpShapes.InvokeMethod('item', ));
        tmpLeft := SysUtils.StrToFloat(ObjectHelper.ToString(tmpShapeItem.PropertyGet('left', [])));
        tmpTop := SysUtils.StrToFloat(ObjectHelper.ToString(tmpShapeItem.PropertyGet('top', [])));
        //判断当前图片是否在指定的单元格内
        if (tmpLeft >= left) and (tmpLeft < (left + width))
          and (tmpTop >= top) and (tmpTop < (top + height)) then
        begin
          //将图片复制到剪贴板
          tmpShapeItem.InvokeMethod('CopyPicture',[1,2]);

          lTragetBmp := Business.System.TBitmap.Create;
          lSourceBmp := Business.System.TBitmap.Create;
          try
            lSourceBmp.LoadFromClipboardFormat(Borland.Delphi.Windows.CF_BITMAP,
              clipbrd.Clipboard.GetAsHandle(Borland.Delphi.Windows.CF_BITMAP), 0);
            SmoothResize(lTragetBmp, lSourceBmp, $fffffe);
            AJPG.Assign(lTragetBmp);
            Result := True;
          finally
            lSourceBmp.Free;
            lTragetBmp.Free;
          end;
        end;
      end;
    except
      raise 'GetPic Failed';
    end;
  finally
    //释放进程
    dispatchApplication.InvokeMethod('quit', []);
    (objWorkBooks as System.IDisposable).Dispose;
    (objApplication as System.IDisposable).Dispose;
  end;
end;
回复 支持 反对

使用道具 举报

发表于 2010-5-24 09:44:08 | 显示全部楼层
tmpShapes := DispatchHelper.Create(tmpSheet.PropertyGet('Shapes', []));

不要这样写,把里面的拆出来,然后释放。

看看你1楼连接中的6楼。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-5-24 10:14:02 | 显示全部楼层
tmpShapes := DispatchHelper.Create(tmpSheet.PropertyGet('Shapes', []));
拆成
      objShapes := dispatchApplication.PropertyGet('Shapes', []);
      tmpShapes := DispatchHelper.Create(objShapes);
然后增加
(objShapes as System.IDisposable).Dispose;
是这样吗?
回复 支持 反对

使用道具 举报

发表于 2010-5-24 10:15:28 | 显示全部楼层
对。就是帖子连接中6楼第三点说的
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-5-24 10:20:06 | 显示全部楼层

运行效果还是一样

改成:
function TINFO_PROJECTDETAIL.GetPicFromExcel(AFileName: string; AJPG: TJPEGImage;
  ASheetIndex, ARowIndex, AColumnIndex:Integer): Boolean;
var
  objApplication, objWorkBooks: object;
  objShapes, objSheet: object;
  dispatchApplication, dispatchWorkBooks, dispatchSourceWB: System.DispatchHelper;
  tmpCell, tmpSheet, tmpShapes, tmpShapeItem: System.DispatchHelper;
  left, top, height, width: Double;
  tmpLeft,tmpTop: Double;
  i, ShapeCount: Integer;   //图形个数
  lSourceBmp: Business.System.TBitmap;
  lTragetBmp: Business.System.TBitmap;
  //l1, l2, l3: TStream;
begin
  Result := False;
  objApplication := ComObj.CreateOleObject('Excel.Application');
  dispatchApplication := DispatchHelper.Create(objApplication);
  objWorkBooks := dispatchApplication.PropertyGet('WorkBooks',[]);
  dispatchWorkBooks := DispatchHelper.Create(objWorkBooks);
  try
    try
      //创建Excel对象并打开
      dispatchSourceWB := DispatchHelper.Create(dispatchWorkBooks.InvokeMethod('Open',[AFileName]));
      //获取指定单元格的左 上 宽 高
      tmpCell := DispatchHelper.Create(dispatchApplication.PropertyGet('cells', [ARowIndex, AColumnIndex]));
      left := SysUtils.StrToFloat(ObjectHelper.ToString(tmpCell.PropertyGet('left', [])));
      top := SysUtils.StrToFloat(ObjectHelper.ToString(tmpCell.PropertyGet('top', [])));
      width := SysUtils.StrToFloat(ObjectHelper.ToString(tmpCell.PropertyGet('width', [])));
      height := SysUtils.StrToFloat(ObjectHelper.ToString(tmpCell.PropertyGet('height', [])));
      //获取全部的格数
      objSheet := dispatchApplication.PropertyGet('Sheets', [ASheetIndex]);
      tmpSheet := DispatchHelper.Create(objSheet);
      objShapes := tmpSheet.PropertyGet('Shapes', []);
      tmpShapes := DispatchHelper.Create(objShapes);
      ShapeCount := SysUtils.StrToInt(ObjectHelper.ToString(tmpShapes.PropertyGet('Count', [])));
      for i := 1 to ShapeCount do
      begin
        tmpShapeItem := DispatchHelper.Create(tmpShapes.InvokeMethod('item', ));
        tmpLeft := SysUtils.StrToFloat(ObjectHelper.ToString(tmpShapeItem.PropertyGet('left', [])));
        tmpTop := SysUtils.StrToFloat(ObjectHelper.ToString(tmpShapeItem.PropertyGet('top', [])));
        //判断当前图片是否在指定的单元格内
        if (tmpLeft >= left) and (tmpLeft < (left + width))
          and (tmpTop >= top) and (tmpTop < (top + height)) then
        begin
          //将图片复制到剪贴板
          tmpShapeItem.InvokeMethod('CopyPicture',[1,2]);

          lTragetBmp := Business.System.TBitmap.Create;
          lSourceBmp := Business.System.TBitmap.Create;
          try
            lSourceBmp.LoadFromClipboardFormat(Borland.Delphi.Windows.CF_BITMAP,
              clipbrd.Clipboard.GetAsHandle(Borland.Delphi.Windows.CF_BITMAP), 0);
            SmoothResize(lTragetBmp, lSourceBmp, $fffffe);
            AJPG.Assign(lTragetBmp);
            Result := True;
          finally
            lSourceBmp.Free;
            lTragetBmp.Free;
          end;
        end;
      end;
    except
      raise 'GetPic Failed';
    end;
  finally
    //释放进程
    dispatchApplication.InvokeMethod('quit', []);
    (objSheet as System.IDisposable).Dispose;
    (objShapes as System.IDisposable).Dispose;
    (objWorkBooks as System.IDisposable).Dispose;
    (objApplication as System.IDisposable).Dispose;
  end;
end;

excel进程还是需要退出Business才释放呢
回复 支持 反对

使用道具 举报

发表于 2010-5-24 10:24:13 | 显示全部楼层
dispatchSourceWB := DispatchHelper.Create(dispatchWorkBooks.InvokeMethod('Open',[AFileName]));


这个也要改。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-5-24 10:32:47 | 显示全部楼层

这样ok吗

function TINFO_PROJECTDETAIL.GetPicFromExcel(AFileName: string; AJPG: TJPEGImage;
  ASheetIndex, ARowIndex, AColumnIndex:Integer): Boolean;
var
  objApplication, objWorkBooks: object;
  objSourceWB, objCell, objSheet, objShapes, objShapeItem: object;
  dispatchApplication, dispatchWorkBooks, dispatchSourceWB: System.DispatchHelper;
  tmpCell, tmpSheet, tmpShapes, tmpShapeItem: System.DispatchHelper;
  left, top, height, width: Double;
  tmpLeft,tmpTop: Double;
  i, ShapeCount: Integer;   //图形个数
  lSourceBmp: Business.System.TBitmap;
  lTragetBmp: Business.System.TBitmap;
  //l1, l2, l3: TStream;
begin
  Result := False;
  objApplication := ComObj.CreateOleObject('Excel.Application');
  dispatchApplication := DispatchHelper.Create(objApplication);
  objWorkBooks := dispatchApplication.PropertyGet('WorkBooks',[]);
  dispatchWorkBooks := DispatchHelper.Create(objWorkBooks);
  try
    try
      //创建Excel对象并打开
      objSourceWB := dispatchWorkBooks.InvokeMethod('Open',[AFileName]);
      dispatchSourceWB := DispatchHelper.Create(objSourceWB);
      //获取指定单元格的左 上 宽 高
      objCell := dispatchApplication.PropertyGet('cells', [ARowIndex, AColumnIndex]);
      tmpCell := DispatchHelper.Create(objCell);
      left := SysUtils.StrToFloat(ObjectHelper.ToString(tmpCell.PropertyGet('left', [])));
      top := SysUtils.StrToFloat(ObjectHelper.ToString(tmpCell.PropertyGet('top', [])));
      width := SysUtils.StrToFloat(ObjectHelper.ToString(tmpCell.PropertyGet('width', [])));
      height := SysUtils.StrToFloat(ObjectHelper.ToString(tmpCell.PropertyGet('height', [])));
      //获取全部的格数
      objSheet := dispatchApplication.PropertyGet('Sheets', [ASheetIndex]);
      tmpSheet := DispatchHelper.Create(objSheet);
      objShapes := tmpSheet.PropertyGet('Shapes', []);
      tmpShapes := DispatchHelper.Create(objShapes);
      ShapeCount := SysUtils.StrToInt(ObjectHelper.ToString(tmpShapes.PropertyGet('Count', [])));
      for i := 1 to ShapeCount do
      begin
        objShapeItem := tmpShapes.InvokeMethod('item', );
        tmpShapeItem := DispatchHelper.Create(objShapeItem);
        tmpLeft := SysUtils.StrToFloat(ObjectHelper.ToString(tmpShapeItem.PropertyGet('left', [])));
        tmpTop := SysUtils.StrToFloat(ObjectHelper.ToString(tmpShapeItem.PropertyGet('top', [])));
        //判断当前图片是否在指定的单元格内
        if (tmpLeft >= left) and (tmpLeft < (left + width))
          and (tmpTop >= top) and (tmpTop < (top + height)) then
        begin
          //将图片复制到剪贴板
          tmpShapeItem.InvokeMethod('CopyPicture',[1,2]);

          lTragetBmp := Business.System.TBitmap.Create;
          lSourceBmp := Business.System.TBitmap.Create;
          try
            lSourceBmp.LoadFromClipboardFormat(Borland.Delphi.Windows.CF_BITMAP,
              clipbrd.Clipboard.GetAsHandle(Borland.Delphi.Windows.CF_BITMAP), 0);
            SmoothResize(lTragetBmp, lSourceBmp, $fffffe);
            AJPG.Assign(lTragetBmp);
            Result := True;
          finally
            lSourceBmp.Free;
            lTragetBmp.Free;
          end;
        end;
      end;
    except
      raise 'GetPic Failed';
    end;
  finally
    //释放进程
    dispatchApplication.InvokeMethod('quit', []);
    (objShapeItem as System.IDisposable).Dispose;
    (objShapes as System.IDisposable).Dispose;
    (objSheet as System.IDisposable).Dispose;
    (objCell as System.IDisposable).Dispose;
    (objSourceWB as System.IDisposable).Dispose;
    (objWorkBooks as System.IDisposable).Dispose;
    (objApplication as System.IDisposable).Dispose;
  end;
end;
回复 支持 反对

使用道具 举报

发表于 2010-5-24 10:41:43 | 显示全部楼层
恩,会释放么?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Justep Inc.

GMT+8, 2025-7-10 05:57 , Processed in 0.050056 second(s), 15 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表