AI muốn lập trình DLL cho Excel và các loại bằng Delphi thì xem video này nhé!

Liên hệ QC

Nguyễn Duy Tuân

Nghị Hách
Thành viên danh dự
Tham gia
13/6/06
Bài viết
4,649
Được thích
10,138
Giới tính
Nam
Nghề nghiệp
Giáo viên, CEO tại Bluesofts
Lần chỉnh sửa cuối:
Các Bạn cho Mình hỏi chút
Mình sử dụng code sau test thử sao có 2 dòng sau lúc nó chạy lúc Không mà chưa biết vì sao ... hay viết sai cái gì
Rất mong trợ giúp
Mã:
ShowMessage(sheet.name); //dòng này lúc chạy lúc không
sheet.Range['a1', 'a1'] := 'Kiều Mạnh';    //dòng này lúc chạy lúc không
Toàn bộ code như sau:
Mã:
procedure Get_ExcelApp;
var
  Excel: OleVariant;
  sheet: OleVariant;
  XlVersion: Integer;
begin
  try
    Excel := GetActiveOleObject('EXCEL.Application');
    XlVersion := Trunc(Excel.Application.Version);
    ShowMessage('GetActiveOleObject');
    ShowMessage(IntToStr(XlVersion));
    sheet := Excel.ActiveSheet;
    ShowMessage(sheet.name); //dòng này lúc chạy lúc không
    sheet.Range['a1', 'a1'] := 'Kiều Mạnh';    //dòng này lúc chạy lúc không
  except
    Excel := CreateOleObject('EXCEL.Application');
    XlVersion := Trunc(Excel.Application.Version);
    ShowMessage('CreateOleObject');
    ShowMessage(IntToStr(XlVersion));
    sheet := Excel.ActiveSheet;
    ShowMessage(sheet.name); //dòng này lúc chạy lúc không
    sheet.Range['a1', 'a1'] := 'Kiều Mạnh';    //dòng này lúc chạy lúc không
  end;
  Excel := Unassigned;
end;
1/ Nếu mở 1 File Excel mới tinh lên chưa Lưu có đường dẫn trên ổ cứng là tịt !!
2/ Nếu 1 File có có dữ liệu đã lưu trên Ổ cứng thì OK ???

Có vài vấn đề cần làm rõ hơn:
1. Hàm GetActiveOleObject giống GetObject của VBA/VB6. Nó chit chạy nếu Excel chạy với “Run as Administrator”.
2. Range cách dùng Range[‘A1’, EmptyParam] (không muốn viết tham số thứ hai)
3. Code của bạn là ghi dữ liệu vào file đang mở, nó sẽ lỗi nếu Excel mới tạo không có file nào. Nên bạn phải viết dòng code
Excel := CreateOleObject('EXCEL.Application');
Excel.Workbooks.Add

(*) Bạn xem video tôi hướng dẫn ghi dữ liệu và vẽ biểu đồ Excel đây để thêm kinh nghiệm
 
Upvote 0
Debug đi, debug vào source của Delphi luôn, xem tại sao failed.
Quăng lý do failed, file source, dòng lên đây.
Code mà không biết debug là vứt.
Những dòng lệnh trong khối except...end sẽ được thực thi khi nào mà viết là "lúc chạy lúc không ?????"
Đọc help của Delphi về cơ chế exception handling của nó chưa ?
try finally except mục đích làm gì ?
chịu ... coi help mà biết hết cũng chết liền .... Chỉ Em út chút đi ... mò lâu quá đi
 
Upvote 0
Có vài vấn đề cần làm rõ hơn:
1. Hàm GetActiveOleObject giống GetObject của VBA/VB6. Nó chit chạy nếu Excel chạy với “Run as Administrator”.
2. Range cách dùng Range[‘A1’, EmptyParam] (không muốn viết tham số thứ hai)
3. Code của bạn là ghi dữ liệu vào file đang mở, nó sẽ lỗi nếu Excel mới tạo không có file nào. Nên bạn phải viết dòng code
Excel := CreateOleObject('EXCEL.Application');
Excel.Workbooks.Add

(*) Bạn xem video tôi hướng dẫn ghi dữ liệu và vẽ biểu đồ Excel đây để thêm kinh nghiệm
Cho Mình hỏi chút có cách nào khác khai báo và sử dụng trên Excel mà bỏ cái dòng mình tô đậm đó không
mà sử dụng tốt cho Office 2010 to 2019
 
Upvote 0
Có vài vấn đề cần làm rõ hơn:
1. Hàm GetActiveOleObject giống GetObject của VBA/VB6. Nó chit chạy nếu Excel chạy với “Run as Administrator”.
2. Range cách dùng Range[‘A1’, EmptyParam] (không muốn viết tham số thứ hai)
3. Code của bạn là ghi dữ liệu vào file đang mở, nó sẽ lỗi nếu Excel mới tạo không có file nào. Nên bạn phải viết dòng code
Excel := CreateOleObject('EXCEL.Application');
Excel.Workbooks.Add

(*) Bạn xem video tôi hướng dẫn ghi dữ liệu và vẽ biểu đồ Excel đây để thêm kinh nghiệm
Quá hay ... chắc coi tới lui sẻ làm ok đó
Nếu được cho Mình xin code Phần kết nối và gán kết quả tới Excel đi .... thì Mạnh học sẻ rất nhanh thôi, cơ bản kiến thức Delphi Mạnh Học ở đây và Internet tạm ổn rồi
Xin cảm ơn
 
Upvote 0
Upvote 0
Cái đó là bắt buộc. Nếu viết add-in thì không cần.
Có vài vấn đề cần làm rõ hơn:
1. Hàm GetActiveOleObject giống GetObject của VBA/VB6. Nó chit chạy nếu Excel chạy với “Run as Administrator”.
2. Range cách dùng Range[‘A1’, EmptyParam] (không muốn viết tham số thứ hai)
3. Code của bạn là ghi dữ liệu vào file đang mở, nó sẽ lỗi nếu Excel mới tạo không có file nào. Nên bạn phải viết dòng code
Excel := CreateOleObject('EXCEL.Application');
Excel.Workbooks.Add

(*) Bạn xem video tôi hướng dẫn ghi dữ liệu và vẽ biểu đồ Excel đây để thêm kinh nghiệm
Xem tới lui qua lại mấy lần đã học xong ... vậy là cái Add-Ins COM + Ribbon menu trên Delphi của Mạnh cơ bản đã hoàn thành
quá hay luôn .... Mạnh cảm ơn nhiều
1592705408017.png
 
Upvote 0
Xem tới lui qua lại mấy lần đã học xong ... vậy là cái Add-Ins COM + Ribbon menu trên Delphi của Mạnh cơ bản đã hoàn thành
quá hay luôn .... Mạnh cảm ơn nhiều
View attachment 239654

Nếu đã chạy COM add-in tbif hãy gán biến Excel vào tham số Application trong sự kiện OnConnection nhé. Sau này không phải Create hay get Object gì cả.
 
Upvote 0
Nếu đã chạy COM add-in tbif hãy gán biến Excel vào tham số Application trong sự kiện OnConnection nhé. Sau này không phải Create hay get Object gì cả.
Chắc là code sau quá .... càng đi sâu lại khám phá ra nhiều thứ hay ... Cảm ơn chỉ cho Mạnh
Mã:
procedure TCoMultipleUIThreadsDemo.OnConnection(const Application: IDispatch;
  ConnectMode: ext_ConnectMode; const AddInInst: IDispatch;
  var custom: PSafeArray);
begin
Mới biết khai báo tham số và đối số sử dụng cho File *.ridl vậy là qua nhưng bài của Bạn + sự đam mê code của Mạnh cơ bản học được rất nhiều đó

1592707374440.png
Vậy cơ bản Viết Add-ins COM trên Delphi cho Excel tạm OK rồi ... khó khăn lại nhờ Tiếp
 
Upvote 0
Rảnh mình mới thử thì thấy như sau

Code Sau chạy tốt
Mã:
procedure TForm1.Button1Click(Sender: TObject);
begin { Tạo 1 File Excel Moi }
  FExcelApp := TExcelApplication.Create(nil);
  FExcelApp.ConnectKind := cknewinstance;
  FExcelApp.Connect;
  FExcelApp.Visible[0] := true;
  FExcelApp.Workbooks.Add(EmptyParam, 0);
end;

Code Sau thì báo lỗi Mình chưa biết do khai báo thiếu gì hay Viết sai
Mã:
procedure TForm1.Button2Click(Sender: TObject);
var
  d: Integer; // Last row
  sh: _WorksheetDisp;
  Sheet: _WorksheetDisp;
begin
  sh := _WorksheetDisp(FExcelApp.ActiveSheet);
  sh.Cells._Default['a1', EmptyParam].Value := 'Kiều Mạnh';  //Không chạy và báo Lỗi
  ShowMessage(sh.Name);  //không chạy
end;

Hình báo Lỗi khi chạy Add-Ins Mở 1 File Excel mới lên chưa có Lưu
1592720028113.png
Mong chỉ dùm ... xin cảm ơn
 
Upvote 0
Rảnh mình mới thử thì thấy như sau

Code Sau chạy tốt
Mã:
procedure TForm1.Button1Click(Sender: TObject);
begin { Tạo 1 File Excel Moi }
  FExcelApp := TExcelApplication.Create(nil);
  FExcelApp.ConnectKind := cknewinstance;
  FExcelApp.Connect;
  FExcelApp.Visible[0] := true;
  FExcelApp.Workbooks.Add(EmptyParam, 0);
end;

Code Sau thì báo lỗi Mình chưa biết do khai báo thiếu gì hay Viết sai
Mã:
procedure TForm1.Button2Click(Sender: TObject);
var
  d: Integer; // Last row
  sh: _WorksheetDisp;
  Sheet: _WorksheetDisp;
begin
  sh := _WorksheetDisp(FExcelApp.ActiveSheet);
  sh.Cells._Default['a1', EmptyParam].Value := 'Kiều Mạnh';  //Không chạy và báo Lỗi
  ShowMessage(sh.Name);  //không chạy
end;

Hình báo Lỗi khi chạy Add-Ins Mở 1 File Excel mới lên chưa có Lưu
View attachment 239660
Mong chỉ dùm ... xin cảm ơn
Đã truyền vào Cells thì nó phải là số chứ anh:

Mã:
procedure TForm1.Button1Click(Sender: TObject);
var
  d: Integer; // Last row
  sh: _WorksheetDisp;
   
begin
  sh := _WorksheetDisp(FExcelApp.ActiveSheet);
  sh.Cells._Default[1,1].Value :='Kiều Mạnh' ;
  ShowMessage(sh.Name);  //ok
end;
 
Lần chỉnh sửa cuối:
Upvote 0
Đã truyền vào Cells thì nó phải là số chứ anh:

Mã:
procedure TForm1.Button1Click(Sender: TObject);
var
  d: Integer; // Last row
  sh: _WorksheetDisp;
  
begin
  sh := _WorksheetDisp(FExcelApp.ActiveSheet);
  sh.Cells._Default[1,1].Value :='Kiều Mạnh' ;
  ShowMessage(sh.Name);  //ok
end;
Mới thử xong nó vẫn báo lỗi vậy ... Hay DLL COM Add-ins nó khai báo có gì khác ???

1592808541562.png
1592808592300.png
 
Upvote 0
Chịu thử các kiểu rồi ... mai mốt rảnh làm cái Form.exe chạy xem sao ... còn Add-ins COM DLL là thua rồi đó
 
Upvote 0
Bạn gửi đoạn code nằm trong lệnh chạy lỗi xem nào?
Code chay báo Lỗi
Mã:
procedure TForm1.GetRangeClick(Sender: TObject);
var
  d: Integer; // Last row
  sh: _WorksheetDisp;
begin
  sh := _WorksheetDisp(FExcelApp.ActiveSheet);
  sh.Cells._Default[1, 1].Value := 'Kiều Mạnh';
  ShowMessage(sh.name);
end;

Khai báo Trên Form
Mã:
uses
  System.Win.ComObj,
  Excel2010, Vcl.oleServer,
  Winapi.Windows, Winapi.Messages,
  System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  Vcl.StdCtrls, Vcl.Buttons, Vcl.ComCtrls,
  Vcl.ExtCtrls, Vcl.DBCtrls;

type
  TForm1 = class(TForm)
    OpenDialog1: TOpenDialog;
    SpeedButton1: TSpeedButton;
    DBRadioGroup1: TDBRadioGroup;
    DBListBox1: TDBListBox;
    Edit1: TEdit;
    TaoWorkBook: TButton;
    GetRange: TButton;
    Label1: TLabel;
    Button1: TButton;
    Button2: TButton;
    cmdDongExcel: TButton;
    // manh them khai bao
    procedure SpeedButton1Click(Sender: TObject);
    procedure TaoWorkBookClick(Sender: TObject);
    procedure GetRangeClick(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure cmdDongExcelClick(Sender: TObject);
  private
    { Private declarations }
    FExcelApp: TExcelApplication; // Uses Excel2010
  public
    { Public declarations }
  end;
Xem dùm Mạnh hay Uses nó thiếu cái gì

Ý là khi mở Form trên Add-ins Ribbon Excel lên thì nó lấy ActiveSheet của bất cứ File nào đó đang mở... xong tùy chọn gán dữ liệu Xuống Range
VD: có nhiều ActiveWorkbook đang mở thì kho Form Show lên trên ActiveSheet của ActiveWorkbook đó thì tùy chọn gán xuống Range của ActiveSheet đó

Thiết kế Y trang cái Tools SQL sau Mạnh viết trên VB6 là File EXE ... còn Delphi là DLL COM Add-Ins
 

File đính kèm

  • SQLDatabase.rar
    30.9 KB · Đọc: 6
Lần chỉnh sửa cuối:
Upvote 0
Code chay báo Lỗi
Mã:
procedure TForm1.GetRangeClick(Sender: TObject);
var
  d: Integer; // Last row
  sh: _WorksheetDisp;
begin
  sh := _WorksheetDisp(FExcelApp.ActiveSheet);
  sh.Cells._Default[1, 1].Value := 'Kiều Mạnh';
  ShowMessage(sh.name);
end;

Khai báo Trên Form
Mã:
uses
  System.Win.ComObj,
  Excel2010, Vcl.oleServer,
  Winapi.Windows, Winapi.Messages,
  System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  Vcl.StdCtrls, Vcl.Buttons, Vcl.ComCtrls,
  Vcl.ExtCtrls, Vcl.DBCtrls;

type
  TForm1 = class(TForm)
    OpenDialog1: TOpenDialog;
    SpeedButton1: TSpeedButton;
    DBRadioGroup1: TDBRadioGroup;
    DBListBox1: TDBListBox;
    Edit1: TEdit;
    TaoWorkBook: TButton;
    GetRange: TButton;
    Label1: TLabel;
    Button1: TButton;
    Button2: TButton;
    cmdDongExcel: TButton;
    // manh them khai bao
    procedure SpeedButton1Click(Sender: TObject);
    procedure TaoWorkBookClick(Sender: TObject);
    procedure GetRangeClick(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure cmdDongExcelClick(Sender: TObject);
  private
    { Private declarations }
    FExcelApp: TExcelApplication; // Uses Excel2010
  public
    { Public declarations }
  end;
Xem dùm Mạnh hay Uses nó thiếu cái gì

Ý là khi mở Form trên Add-ins Ribbon Excel lên thì nó lấy ActiveSheet của bất cứ File nào đó đang mở... xong tùy chọn gán dữ liệu Xuống Range
VD: có nhiều ActiveWorkbook đang mở thì kho Form Show lên trên ActiveSheet của ActiveWorkbook đó thì tùy chọn gán xuống Range của ActiveSheet đó

Thiết kế Y trang cái Tools SQL sau Mạnh viết trên VB6 là File EXE ... còn Delphi là DLL COM Add-Ins
Anh thử file đính kèm nhé
 

File đính kèm

  • TestRange.rar
    2.8 MB · Đọc: 12
Upvote 0
Anh thử file đính kèm nhé
Rảnh tải code đó xem ( Code Của tây đó nha )
COM Add-Ins Delphi đó nghiên cứu xem và thử trên cái Form đó xem là thấy cái lỗi Mạnh đang bị
Mạnh Ứng dụng File đó Viết thêm Menu vào thôi ...
Vọc File đó đi xu hướng sẻ có nhiều thứ hay đấy

nếu ko thích cái Form đó load khi Excel load thì xóa nó đi tạo cái Mới xong viết Menu gọi nó lên thì cũng lỗi như vậy
 

File đính kèm

  • InputInExcel.rar
    13.3 KB · Đọc: 14
Lần chỉnh sửa cuối:
Upvote 0
Rảnh tải code đó xem ( Code Của tây đó nha )
COM Add-Ins Delphi đó nghiên cứu xem và thử trên cái Form đó xem là thấy cái lỗi Mạnh đang bị
Mạnh Ứng dụng File đó Viết thêm Menu vào thôi ...
Vọc File đó đi xu hướng sẻ có nhiều thứ hay đấy

nếu ko thích cái Form đó load khi Excel load thì xóa nó đi tạo cái Mới xong viết Menu gọi nó lên thì cũng lỗi như vậy
Cho đến tận bài #1097 bạn chỉ toàn nói nhát gừng, đính từng mẩu code, nên muốn đoán mò vẫn rất khó. Bạn tung mẩu code:
Mã:
procedure TForm1.GetRangeClick(Sender: TObject);
var
  d: Integer; // Last row
  sh: _WorksheetDisp;
begin
  sh := _WorksheetDisp(FExcelApp.ActiveSheet);
  sh.Cells._Default[1, 1].Value := 'Kiều Mạnh';
  ShowMessage(sh.name);
end;
nhưng bạn không tiết lộ bí mật là từ đâu bạn đã có FExcelApp.

Ở bài #1098 bạn đính kèm toàn bộ code nên chả cần đoán mò nữa. Sự thật nó trần trụi hay trần truồng thế nào thì nhìn rõ mồn một.

Bạn hãy tìm trong tất cả các tập tin PAS xem có chỗ nào khởi tạo hay đọc từ đâu đó vào FExcelApp. Tôi đeo kính, soi đèn pin nhưng không tìm thấy. Tức ở thời điểm nhấn nút GetRange thì FExcelApp = NIL. Không có lỗi mới là chuyện lạ.

Tôi rất ngại trả lời bạn và một bạn nữa vì các bạn thường chỉ nói nhát gừng, và đính kèm 1 mẩu code ngắn. Không một lời giải thích thêm.

Bạn viết code nhưng bạn không biết debug ở mức tối thiểu?
 
Lần chỉnh sửa cuối:
Upvote 0
Cho đến tận bài #1097 bạn chỉ toàn nói nhát gừng, đính từng mẩu code, nên muốn đoán mò vẫn rất khó. Bạn tung mẩu code:
Mã:
procedure TForm1.GetRangeClick(Sender: TObject);
var
  d: Integer; // Last row
  sh: _WorksheetDisp;
begin
  sh := _WorksheetDisp(FExcelApp.ActiveSheet);
  sh.Cells._Default[1, 1].Value := 'Kiều Mạnh';
  ShowMessage(sh.name);
end;
nhưng bạn không tiết lộ bí mật là từ đâu bạn đã có FExcelApp.

Ở bài #1098 bạn đính kèm toàn bộ code nên chả cần đoán mò nữa. Sự thật nó trần trụi hay trần truồng thế nào thì nhìn rõ mồn một.

Bạn hãy tìm trong tất cả các tập tin PAS xem có chỗ nào khởi tạo hay đọc từ đâu đó vào FExcelApp. Tôi đeo kính, soi đèn pin nhưng không tìm thấy. Tức ở thời điểm nhấn nút GetRange thì FExcelApp = NIL. Không có lỗi mới là chuyện lạ.

Tôi rất ngại trả lời bạn và một bạn nữa vì các bạn thường chỉ nói nhát gừng, và đính kèm 1 mẩu code ngắn. Không một lời giải thích thêm.

Bạn viết code nhưng bạn không biết debug ở mức tối thiểu?
Em mới thử viết kiểu vầy nó vẫn báo lỗi ... Anh xem Em viết sai cái gì hay thiếu cái gì viết lại dùm Em với
Cảm Ơn Anh :D
Mã:
procedure TForm1.Button3Click(Sender: TObject);
var
  ExcelApp: TExcelApplication;
  ExWorkbook: TExcelWorkbook;
  ExSheet: TExcelWorksheet;
begin
  ExcelApp := TExcelApplication.Create(nil);
  ExcelApp.Connect;
  ExWorkbook := TExcelWorkbook.Create(nil);
  ExSheet := TExcelWorksheet.Create(nil);
  try
    ExWorkbook.ConnectTo(ExcelApp.ActiveWorkbook as _Workbook);
    ExSheet.ConnectTo(ExWorkbook.ActiveSheet as _Worksheet);
    ShowMessage(ExSheet.name);
  finally
    if Assigned(ExcelApp) then
    begin
      ExcelApp.free;
      ExWorkbook.free;
      ExSheet.free;
    end;
  end;
end;
Code trên Mở File Excel Mới lên Chạy lần 1 báo lỗi
Loi.PNG

Thoát Form chạy Lần thứ 2 Ok ... gần đúng rồi đó
ok.PNG

Anh Viết lại dùm Em với sao cũng File Excel đó chạy Form lần 1 báo lỗi ... Close Form xong chạy lại thì Ok ... Em chịu ko biết tại sao Luôn
 
Lần chỉnh sửa cuối:
Upvote 0
Web KT
Back
Top Bottom