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

PhanTuHuong

Excel & AutoCad & VBA & VB.NET
Thành viên danh dự
Tham gia ngày
13 Tháng sáu 2006
Bài viết
6,871
Được thích
23,457
Điểm
1,860
Nơi ở
Hà Nội

kieu manh

IIIIIIIIIIIIIIIII
Tham gia ngày
9 Tháng sáu 2012
Bài viết
3,616
Được thích
2,472
Điểm
560
Nơi ở
IIIIIIIIIIIIIIIII
Vẫn chưa đâu bạn à! Nhưng nếu có ý định nghiên cứu ngôn ngữ lập trình thứ hai nào đó thì tôi sẽ bắt đầu với C++ hoặc C#
em nghe nói nếu tự học cái đó khó hơn lên trời ấy ... mà tuổi anh em mình ngoài U40 + n rồi ko biết rồi học sao nữa ?!

Em thấy Delphi nó có cái chi đó na ná như VBA và nó viết 1 code duy nhất Make chạy đa nền tảng nên Em mới chịu khó vọc xem sao đó mà

Nhớ ngày đầu Em chuyển qua VB6 cũng rất khó khăn việc khai báo và cú pháp viết sao cho nó hiểu mình vọc diết xong vượt qua cái ngưởng đó vậy là em viết Thư Viện *.dll thấy Tạm ok

Giờ vọc qua Delphi nếu có ai đó có tấm lòng vàng cho 1, 2 code mẫu theo yêu cầu từ đó em mổ sẻ ra từng bước vượt qua cái ngưởng khó khăn ban đầu là tạm ok đó Anh

Nhưng kẹt nổi chưa thấy ai tốt vậy cả Anh ạ .... phải chi anh Biết Em tin 100% anh cho Em ngay lập tức ha -0-0-0-
 

Hieu011

Thành viên mới
Tham gia ngày
12 Tháng chín 2015
Bài viết
13
Được thích
5
Điểm
165
Tuổi
20
Em được học Pascal, từ hồi trường em còn có cái phòng thực hành toàn máy tính cổ, thỉnh thoảng không hiểu linh kiện máy tính chập cháy kiểu gì bốc khói um cả lên thế là lớp được giải tán :yahoo:. Đi thi thì rụng như sung. Chả là bọn em thi 2 phần viết và thực hành, nghĩ cái cảnh viết mấy tờ giấy thi toàn câu lệnh Pascal mà ớn. Còn thi thực hành thì hên sui (Nếu được máy ngon, thầy dễ tính thì yên tâm chứ gặp máy lởm thì mình chết theo nó luôn), với lại hồi đó sinh viên mà có máy tính riêng là Vip lắm.
Đúng là học Pascal chỉ để rèn luyện tư duy (hay để làm cảnh ...), học nghành kỹ thuật nên ra trường đi làm thì toàn dùng CAD, Word, Excel. Dùng Excel mãi thì có nhu cầu mở rộng tính năng, thông qua lập trình trên ứng dụng nền em được biết đến VBA, VSTO và gần đây là Delphi.
Đối với nhu cầu công việc của em làm trên Excel, khi xét về tốc độ thực thi thì VSTO<VBA<Delphi nên em thấy Delphi sẽ là sự lựa chọn cho những ai ưu tiên về thời gian thực thi mã lệnh.
 

Nguyễn Duy Tuân

Nghị Hách
Thành viên danh dự
Tham gia ngày
13 Tháng sáu 2006
Bài viết
4,224
Được thích
9,729
Điểm
860
Nơi ở
Hà Nội
em nghe nói nếu tự học cái đó khó hơn lên trời ấy ... mà tuổi anh em mình ngoài U40 + n rồi ko biết rồi học sao nữa ?!

Em thấy Delphi nó có cái chi đó na ná như VBA và nó viết 1 code duy nhất Make chạy đa nền tảng nên Em mới chịu khó vọc xem sao đó mà

Nhớ ngày đầu Em chuyển qua VB6 cũng rất khó khăn việc khai báo và cú pháp viết sao cho nó hiểu mình vọc diết xong vượt qua cái ngưởng đó vậy là em viết Thư Viện *.dll thấy Tạm ok

Giờ vọc qua Delphi nếu có ai đó có tấm lòng vàng cho 1, 2 code mẫu theo yêu cầu từ đó em mổ sẻ ra từng bước vượt qua cái ngưởng khó khăn ban đầu là tạm ok đó Anh

Nhưng kẹt nổi chưa thấy ai tốt vậy cả Anh ạ .... phải chi anh Biết Em tin 100% anh cho Em ngay lập tức ha -0-0-0-
Không biết bài đầu có đc gọi là lòng tốt không? :) . Phải mất nhiều thời gian mình mới có thể hiểu chắc chắn cơ về tạo DLL theo cách gọi API đó đấy. Ở Việt Nam này chưa có ai làm video hay viết tài liệu hướng dẫn món đó cả (hoặc mình chưa thể tìm ra). Mấy món Java, Python, Rube, .NET không (dùng framework) không thể tạo được loại thư viện biên dịch ra mã máy đó đâu nhé. Dân lập trình hệ thống, thư viện lõi trong các chương trình lớn phải dùng C, C++, Delphi mới làm món đó để tối ưu chương trình. Ví dụ một cái hàm LEFT hay các hàm xử lý chuỗi thôi, Delphi nó dùng mã nguồn là Assempler để tối ưu. Giờ đây tôi đã vén màn ra cho mọi người thấy để lựa chọn... Chỉ cần nhìn thấy "ánh sáng cuối đường hầm" là biết lối đi. Delphi hay .NET không phải món dễ mò như VB6, VBA đâu. Nên bạn cứ cẩn thận đọc tài liệu từng bước. Bạn đang mới học nhưng muốn lấy ngay một ví dụ (có mã nguồn) mà nó cao hẳn hoặc phức tạp (so với người mới biết) để người khác giúp từ đó học là sai phương pháp. Người khác lên đây cũng đòi một ví dụ muốn chia sẻ dữ liệu dùng Socket với giao thức TCP/IP nữa thì loạn ngay. Tôi code cho bạn ví dụ như bạn muốn dưới đây nhưng cũng chỉ để biết ở mức đó hoặc ngẫm ra "ah, nó làm đc thế" chứ không học được gì căn cơ từ đó nếu không có học từ đầu, từng bước. Nếu các bạn muốn chứng minh Delphi làm được gì hay dễ không thì ví dụ đó lại quá nhỏ bé.

(*) Đây là code viết hàm chạy SQL để lấy dữ liệu từ file Excel và đỏ ra một ô trên Excel. Bạn chạy nó trong Delphi hoặc chạy trong VBA thì theo cách khai báo API video bài 1 tôi đã hướng dẫn. Tham số khai báo OleVariant trong Delphi là Variant ở VBA/VB6, Longint chính là Long ở VBA/VB6. Bạn có thể chạy thử nếu khai báo VBA có lỗi thì đưa lên tôi có thể chỉnh cho.

Phần khai báo USES như thế này
Mã:
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Data.DB, Data.Win.ADODB;
Hàm viết thế này
Mã:
function RunSQLToRange(sFullName, sSQL: OleVariant;  Range: OleVariant): Longint; stdcall;
var
  cnn: TADOConnection;
  qry: TADOQuery;
begin
  cnn := TADOConnection.Create(nil);
  try
    cnn.ConnectionString := 'Provider=Microsoft.ACE.OLEDB.12.0;Data Source=' + sFullName +
                                       'Extended Properties="Excel 12.0 Xml;HDR=YES";';
    cnn.Connected := True;
    qry := TADOQuery.Create(nil);
    try
      qry.Connection := cnn;
      qry.SQL.Text := sSQL;
      qry.Open;
      Result := Range.CopyFromRecordset(qry.Recordset); //copy data from recordset to Excel range
    finally
      qry.Free;
    end;
  finally
    cnn.Free;
  end;
end;
Tôi muốn nhắn thêm với bạn một ý nữa là việc bạn chọn cách học kiểu mò mẫm là sai (trong khi có cơ hội để học bản bản từ ebook, vẫn free nhé) và bên cạch đó bạn không nhận ra được giá trị giúp đỡ đúng mức và dùng từ "lòng tốt" là phật lòng người khác mặc dù họ cũng không cần phải được công nhận điều đó.
 
Lần chỉnh sửa cuối:

quanluu1989

Thành viên gắn bó
Tham gia ngày
11 Tháng tư 2013
Bài viết
2,053
Được thích
1,144
Điểm
560
Nơi ở
Nam Định/Thái Nguyên
Trước mình học ở trường đại học được học 2 kỳ visual basic 6.0, lập trình được mấy chương trình nhỏ chuyên ngành, ra trường đi làm thì chẳng ai dùng VB 6.0 cả, chỗ làm thì lại dùng Free pascal sử dụng Lazarus để soạn code và biên dịch, chuyển từ VB 6.0 sang thấy khác hoàn toàn, nhiều cái mới, học thì toàn học vẹt để làm được cái chương trình nhỏ để dùng. Nhưng cái ngôn ngữ này ít người dùng và ít tài liệu tham khảo, nên người hướng dẫn mình code nghỉ làm thì mình cũng nghỉ chơi luôn, Hiện mình đang chuyển sang C# vì thấy nó rất phổ biến, hỗ trợ nhiều, không biết gì thì lên mạng hỏi cái ra ngay.
Mình thấy cái delphi của anh Tuân sử dụng object pascal giống cái trước mình học, nhưng mình thấy dùng C# vẫn khoái hơn, với lại học cái C# nó gần với mấy cái java hơn, nên khi chuyển sang java cũng dễ.
 

giaiphap

Thành viên gạo cội
Tham gia ngày
12 Tháng ba 2007
Bài viết
4,815
Được thích
4,063
Điểm
860
Em thấy cái này cũng định nghiên cứu chơi nhưng tìm giáo trình tiếng việt (em bị dốt tiếng anh) về nó khó quá (Chỉ thấy giáo tình của ĐHCT mà bản 6, trong khi bây giờ đã là 10 rồi). Vậy anh em nào có giáo trình tiếng việt chỉ em tham khảo với.
 

Nguyễn Duy Tuân

Nghị Hách
Thành viên danh dự
Tham gia ngày
13 Tháng sáu 2006
Bài viết
4,224
Được thích
9,729
Điểm
860
Nơi ở
Hà Nội
Trước mình học ở trường đại học được học 2 kỳ visual basic 6.0, lập trình được mấy chương trình nhỏ chuyên ngành, ra trường đi làm thì chẳng ai dùng VB 6.0 cả, chỗ làm thì lại dùng Free pascal sử dụng Lazarus để soạn code và biên dịch, chuyển từ VB 6.0 sang thấy khác hoàn toàn, nhiều cái mới, học thì toàn học vẹt để làm được cái chương trình nhỏ để dùng. Nhưng cái ngôn ngữ này ít người dùng và ít tài liệu tham khảo, nên người hướng dẫn mình code nghỉ làm thì mình cũng nghỉ chơi luôn, Hiện mình đang chuyển sang C# vì thấy nó rất phổ biến, hỗ trợ nhiều, không biết gì thì lên mạng hỏi cái ra ngay.
Mình thấy cái delphi của anh Tuân sử dụng object pascal giống cái trước mình học, nhưng mình thấy dùng C# vẫn khoái hơn, với lại học cái C# nó gần với mấy cái java hơn, nên khi chuyển sang java cũng dễ.
Đúng là Delphi ở Việt Nam dùng ít. Ở Nhật, Pháp, Đức, Nga, Pháp, Mỹ thì nhiều. Search tài liệu Delphi tiếng Anh thì nhiều vô số, tiếng Việt thì hạn chế.
Bài đã được tự động gộp:

Em thấy cái này cũng định nghiên cứu chơi nhưng tìm giáo trình tiếng việt (em bị dốt tiếng anh) về nó khó quá (Chỉ thấy giáo tình của ĐHCT mà bản 6, trong khi bây giờ đã là 10 rồi). Vậy anh em nào có giáo trình tiếng việt chỉ em tham khảo với.
Theo mình thì bạn cứ dùng giáo trình của ĐHCT đi, với người mới bắt đầu khá dễ tiếp cận. Bạn có căn bản rồi thì đọc code trên mạng sẽ nhanh lắm.
 

Hieu011

Thành viên mới
Tham gia ngày
12 Tháng chín 2015
Bài viết
13
Được thích
5
Điểm
165
Tuổi
20
Theo quan điểm cá nhân em thì, Khó khăn với những người không chuyên về tin học hiện nay muốn học Delphi, là chưa tìm được cuốn Ebook giáo trình bằng tiếng Việt nào chất lượng và bài bản.
Để người học bước đầu làm quen và học một cách có hệ thống những kiến thức căn bản rồi từ đó phát triển theo hướng riêng phục vụ công việc của mình.
Còn Ebook bằng tiếng Anh, thì em nói thật là một số thuật ngữ phải là dân chuyên mới hiểu còn không thì khó lắm, vậy phương án học bằng Ebook tiếng anh ngoài sự lỗ lực của bản thân còn cần sự hỗ trợ của chuyên gia về Delphi trên diễn đàn nữa.
Em rất cảm ơn Bác Nguyễn Duy Tuân đã chỉ dẫn và sửa code cho em. Em rất mong bác Tuân và các chuyên gia của diễn đàn tiếp tục đăng bài chia sẻ nhiều hơn Về Delphi để mọi thành viên có cơ hội tiếp cận nó dễ dàng hơn.
 

quanluu1989

Thành viên gắn bó
Tham gia ngày
11 Tháng tư 2013
Bài viết
2,053
Được thích
1,144
Điểm
560
Nơi ở
Nam Định/Thái Nguyên
Đúng là Delphi ở Việt Nam dùng ít. Ở Nhật, Pháp, Đức, Nga, Pháp, Mỹ thì nhiều. Search tài liệu Delphi tiếng Anh thì nhiều vô số, tiếng Việt thì hạn chế.
Bài đã được tự động gộp:



Theo mình thì bạn cứ dùng giáo trình của ĐHCT đi, với người mới bắt đầu khá dễ tiếp cận. Bạn có căn bản rồi thì đọc code trên mạng sẽ nhanh lắm.
Vâng, nhưng việc tìm kiếm ngay cả bằng tiếng anh nó vẫn hạn chế rất nhiều ạ.
 

Nguyễn Duy Tuân

Nghị Hách
Thành viên danh dự
Tham gia ngày
13 Tháng sáu 2006
Bài viết
4,224
Được thích
9,729
Điểm
860
Nơi ở
Hà Nội
Thực ra mình khá bận với công việc hiện tại. Việc làm tư liệu Delphi mất khá nhiều thời gian để dùng câu từ giải thích dễ hiểu, cũng cố thu xếp lắm mình với tạo được cái video hướng dẫn kỹ bài 1 về học Delphi căn bản. Bài học này giúp các bạn biết tạo lập môi trường ban đầu để biên dịch ra chương trình đầu tiên cho mình 'Hello Delphi!". Loạt video về hoạc Delphi tôi muốn xây dựng free để đáp ứng bước học cơ bản nhất để từ đó người Việt biết đến và ứng dụng cho đúng cía mình muốn. Và khuyến khích các bạn cần đọc lại ngôn ngữ Object Pascal.
Với những bạn đã lập trình VBA thì lưu ý là: ngôn ngữ chúng ta lập trình chính là VB - Visual Basic. Việc ta lập trình trong VBA chỉ là dùng ngôn ngữ để can thiệp vào các Object của ứng dụng như Workbook, Worksheet, Range...
Với Delphi cũng thế. Ngôn ngữ là Object Pascal, dùng trong Delphi để điều khiển và tạo ra các Object mà thôi. Vậy nên cần học ngô ngữ Pascal mới làm được Delphi.
 

Hieu011

Thành viên mới
Tham gia ngày
12 Tháng chín 2015
Bài viết
13
Được thích
5
Điểm
165
Tuổi
20
Code sửa theo Delphi như sau:
Khi viết hàm hay procedure cho Delphi để xử lý Excel, bạn luôn truyền tham số Object mẹ cho nó để trong code xử lý nó hoặc thằng con. Không bao giờ trong hàm hay thủ tục con lại đi nhận Excel.Application -> Code này chỉ dành cho thủ tục đầu tiên hoặc hàm trong DLL gửi nó từ VBA vào.

Mã:
Uses
    ComObj;

Function CheckIfSheetExists(Workbook: OleVariant; shName: String): Boolean;
var
    I: Integer;
begin
Result:= False;
       For I := 1 to Workbook.Sheets.Count do
       begin
          If Workbook.Sheets[I].Name = shName Then
          begin
                Result:= True;
                Break; //  hoặc dùng Exit (Break là chỉ thoát khỏi vòng lặp; Exit là thoát khỏi hàm luôn;
          end;
       end;
end;
Cảm ơn bác đã sửa code giúp em!
Ở đây là bác dùng vòng lặp For .. To . Em có một chút tò mò là Vòng lặp For .. In không hỗ trợ trong Delphi 7 các phiên bản sau mới hỗ trợ. Vậy như trong đoạn Code em nêu trên nếu sửa theo vòng lặp For .. In thì Khai báo biến và viết code thế nào ạ?
 

kieu manh

IIIIIIIIIIIIIIIII
Tham gia ngày
9 Tháng sáu 2012
Bài viết
3,616
Được thích
2,472
Điểm
560
Nơi ở
IIIIIIIIIIIIIIIII
Không biết bài đầu có đc gọi là lòng tốt không? :) . Phải mất nhiều thời gian mình mới có thể hiểu chắc chắn cơ về tạo DLL theo cách gọi API đó đấy. Ở Việt Nam này chưa có ai làm video hay viết tài liệu hướng dẫn món đó cả (hoặc mình chưa thể tìm ra). Mấy món Java, Python, Rube, .NET không (dùng framework) không thể tạo được loại thư viện biên dịch ra mã máy đó đâu nhé. Dân lập trình hệ thống, thư viện lõi trong các chương trình lớn phải dùng C, C++, Delphi mới làm món đó để tối ưu chương trình. Ví dụ một cái hàm LEFT hay các hàm xử lý chuỗi thôi, Delphi nó dùng mã nguồn là Assempler để tối ưu. Giờ đây tôi đã vén màn ra cho mọi người thấy để lựa chọn... Chỉ cần nhìn thấy "ánh sáng cuối đường hầm" là biết lối đi. Delphi hay .NET không phải món dễ mò như VB6, VBA đâu. Nên bạn cứ cẩn thận đọc tài liệu từng bước. Bạn đang mới học nhưng muốn lấy ngay một ví dụ (có mã nguồn) mà nó cao hẳn hoặc phức tạp (so với người mới biết) để người khác giúp từ đó học là sai phương pháp. Người khác lên đây cũng đòi một ví dụ muốn chia sẻ dữ liệu dùng Socket với giao thức TCP/IP nữa thì loạn ngay. Tôi code cho bạn ví dụ như bạn muốn dưới đây nhưng cũng chỉ để biết ở mức đó hoặc ngẫm ra "ah, nó làm đc thế" chứ không học được gì căn cơ từ đó nếu không có học từ đầu, từng bước. Nếu các bạn muốn chứng minh Delphi làm được gì hay dễ không thì ví dụ đó lại quá nhỏ bé.

(*) Đây là code viết hàm chạy SQL để lấy dữ liệu từ file Excel và đỏ ra một ô trên Excel. Bạn chạy nó trong Delphi hoặc chạy trong VBA thì theo cách khai báo API video bài 1 tôi đã hướng dẫn. Tham số khai báo OleVariant trong Delphi là Variant ở VBA/VB6, Longint chính là Long ở VBA/VB6. Bạn có thể chạy thử nếu khai báo VBA có lỗi thì đưa lên tôi có thể chỉnh cho.

Phần khai báo USES như thế này
Mã:
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Data.DB, Data.Win.ADODB;
Hàm viết thế này
Mã:
function RunSQLToRange(sFullName, sSQL: OleVariant;  Range: OleVariant): Longint; stdcall;
var
  cnn: TADOConnection;
  qry: TADOQuery;
begin
  cnn := TADOConnection.Create(nil);
  try
    cnn.ConnectionString := 'Provider=Microsoft.ACE.OLEDB.12.0;Data Source=' + sFullName +
                                       'Extended Properties="Excel 12.0 Xml;HDR=YES";';
    cnn.Connected := True;
    qry := TADOQuery.Create(nil);
    try
      qry.Connection := cnn;
      qry.SQL.Text := sSQL;
      qry.Open;
      Result := Range.CopyFromRecordset(qry.Recordset); //copy data from recordset to Excel range
    finally
      qry.Free;
    end;
  finally
    cnn.Free;
  end;
end;
Tôi muốn nhắn thêm với bạn một ý nữa là việc bạn chọn cách học kiểu mò mẫm là sai (trong khi có cơ hội để học bản bản từ ebook, vẫn free nhé) và bên cạch đó bạn không nhận ra được giá trị giúp đỡ đúng mức và dùng từ "lòng tốt" là phật lòng người khác mặc dù họ cũng không cần phải được công nhận điều đó.
Cảm ơn Bạn mình mới chạy thử ko biết nó sai cái gì khi làm thủ tục gọi hàm từ Excel ... nó quay tròn xong thoát luôn file Excel
Bài đã được tự động gộp:

Em thấy cái này cũng định nghiên cứu chơi nhưng tìm giáo trình tiếng việt (em bị dốt tiếng anh) về nó khó quá (Chỉ thấy giáo tình của ĐHCT mà bản 6, trong khi bây giờ đã là 10 rồi). Vậy anh em nào có giáo trình tiếng việt chỉ em tham khảo với.
Thử đọc File sau xem .... Mạnh tải Ở đâu đó quên mất tiêu rồi
 

File đính kèm

Lần chỉnh sửa cuối:

Nguyễn Duy Tuân

Nghị Hách
Thành viên danh dự
Tham gia ngày
13 Tháng sáu 2006
Bài viết
4,224
Được thích
9,729
Điểm
860
Nơi ở
Hà Nội
Cảm ơn Bạn mình mới chạy thử ko biết nó sai cái gì khi làm thủ tục gọi hàm từ Excel ... nó quay tròn xong thoát luôn file Excel
Bài đã được tự động gộp:


Thử đọc File sau xem .... Mạnh tải Ở đâu đó quên mất tiêu rồi
Trong mã nguồn hàm tồi viết thiếu ký tự ";" trong khai báo COnnectionString. Bạn thay thế khối đó bằng code dưới đây là được
Mã:
    cnn.ConnectionString := 'Provider=Microsoft.ACE.OLEDB.12.0;Data Source=' + sFullName +
                                       ';Extended Properties="Excel 12.0 Xml;HDR=YES";';
 

kieu manh

IIIIIIIIIIIIIIIII
Tham gia ngày
9 Tháng sáu 2012
Bài viết
3,616
Được thích
2,472
Điểm
560
Nơi ở
IIIIIIIIIIIIIIIII
Trong mã nguồn hàm tồi viết thiếu ký tự ";" trong khai báo COnnectionString. Bạn thay thế khối đó bằng code dưới đây là được
Mã:
    cnn.ConnectionString := 'Provider=Microsoft.ACE.OLEDB.12.0;Data Source=' + sFullName +
                                       ';Extended Properties="Excel 12.0 Xml;HDR=YES";';
MÌnh mới thử lại nó vẫn vậy ... hay thủ tục gọi Hàm từ Excel mình viết sai ... có thay tham số từ String sang Variant từ Excel nó vẫn vậy
Nhờ bạn xem dùm ... Xin cảm ơn
Mã:
Declare Function RunSQLToRange Lib "VBLibrary.dll" (ByVal ExcelPath As String, ByVal sSQL As String, ByVal Target As Range)

Sub Main()
    Dim FilePath As String, DataRange As String
    ''DataRange = "Data_Nhap$A2:J2000"
    DataRange = "Data_Nhap$"
    ''DataRange = "SELECT * FROM [Data_Nhap$A2:J2000]"
    ''DataRange = "SELECT * FROM [Data_Nhap$]"
  
    FilePath = ThisWorkbook.Path & "\Data.xlsb"
    Call RunSQLToRange(FilePath, DataRange, Range("A2"))
End Sub
 

Nguyễn Duy Tuân

Nghị Hách
Thành viên danh dự
Tham gia ngày
13 Tháng sáu 2006
Bài viết
4,224
Được thích
9,729
Điểm
860
Nơi ở
Hà Nội
MÌnh mới thử lại nó vẫn vậy ... hay thủ tục gọi Hàm từ Excel mình viết sai ... có thay tham số từ String sang Variant từ Excel nó vẫn vậy
Nhờ bạn xem dùm ... Xin cảm ơn
Mã:
Declare Function RunSQLToRange Lib "VBLibrary.dll" (ByVal ExcelPath As String, ByVal sSQL As String, ByVal Target As Range)

Sub Main()
    Dim FilePath As String, DataRange As String
    ''DataRange = "Data_Nhap$A2:J2000"
    DataRange = "Data_Nhap$"
    ''DataRange = "SELECT * FROM [Data_Nhap$A2:J2000]"
    ''DataRange = "SELECT * FROM [Data_Nhap$]"
 
    FilePath = ThisWorkbook.Path & "\Data.xlsb"
    Call RunSQLToRange(FilePath, DataRange, Range("A2"))
End Sub
Bạn khai báo API bên VBA sai. Như tôi đã bôi đậm bài trước, kiểu OleVariant -> Variant. Trong hàm viết ở Delphi tôi dùng OleVariant mà. Bạn khai báo sang String là sai.

Khai báo đúng như sau

Declare Function RunSQLToRange Lib "VBLibrary.dll" (ByVal ExcelPath As Variant, ByVal sSQL As Variant, ByVal Target As Variant)
 

kieu manh

IIIIIIIIIIIIIIIII
Tham gia ngày
9 Tháng sáu 2012
Bài viết
3,616
Được thích
2,472
Điểm
560
Nơi ở
IIIIIIIIIIIIIIIII
Bạn khai báo API bên VBA sai. Như tôi đã bôi đậm bài trước, kiểu OleVariant -> Variant. Trong hàm viết ở Delphi tôi dùng OleVariant mà. Bạn khai báo sang String là sai.

Khai báo đúng như sau

Declare Function RunSQLToRange Lib "VBLibrary.dll" (ByVal ExcelPath As Variant, ByVal sSQL As Variant, ByVal Target As Variant)
MÌnh mới thử lại nó vẫn thế mà code trong Delphi như sau
Mã:
library VBLibrary;

{ Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }

uses
 
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Data.DB, Data.Win.ADODB;
{$R *.res}
//////// Khu Vuc Viet Code 
 function RunSQLToRange(sFullName, sSQL: OleVariant;  Range: OleVariant): Longint; stdcall;
var
  cnn: TADOConnection;
  qry: TADOQuery;
begin
  cnn := TADOConnection.Create(nil);
  try
    {cnn.ConnectionString := 'Provider=Microsoft.ACE.OLEDB.12.0;Data Source=' + sFullName +
                                       'Extended Properties="Excel 12.0 Xml;HDR=YES";'; }
    cnn.ConnectionString := 'Provider=Microsoft.ACE.OLEDB.12.0;Data Source=' + sFullName +
                                       ';Extended Properties="Excel 12.0 Xml;HDR=YES";';
    cnn.Connected := True;
    qry := TADOQuery.Create(nil);
    try
      qry.Connection := cnn;
      qry.SQL.Text := sSQL;
      qry.Open;
      Result := Range.CopyFromRecordset(qry.Recordset); //copy data from recordset to Excel range
    finally
      qry.Free;
    end;
  finally
    cnn.Free;
  end;
end;
///
exports
  RunSQLToRange; 
  begin     
end.
 

Nguyễn Duy Tuân

Nghị Hách
Thành viên danh dự
Tham gia ngày
13 Tháng sáu 2006
Bài viết
4,224
Được thích
9,729
Điểm
860
Nơi ở
Hà Nội
MÌnh mới thử lại nó vẫn thế mà code trong Delphi như sau
Mã:
library VBLibrary;

{ Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }

uses

  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Data.DB, Data.Win.ADODB;
{$R *.res}
//////// Khu Vuc Viet Code
function RunSQLToRange(sFullName, sSQL: OleVariant;  Range: OleVariant): Longint; stdcall;
var
  cnn: TADOConnection;
  qry: TADOQuery;
begin
  cnn := TADOConnection.Create(nil);
  try
    {cnn.ConnectionString := 'Provider=Microsoft.ACE.OLEDB.12.0;Data Source=' + sFullName +
                                       'Extended Properties="Excel 12.0 Xml;HDR=YES";'; }
    cnn.ConnectionString := 'Provider=Microsoft.ACE.OLEDB.12.0;Data Source=' + sFullName +
                                       ';Extended Properties="Excel 12.0 Xml;HDR=YES";';
    cnn.Connected := True;
    qry := TADOQuery.Create(nil);
    try
      qry.Connection := cnn;
      qry.SQL.Text := sSQL;
      qry.Open;
      Result := Range.CopyFromRecordset(qry.Recordset); //copy data from recordset to Excel range
    finally
      qry.Free;
    end;
  finally
    cnn.Free;
  end;
end;
///
exports
  RunSQLToRange;
  begin    
end.
Câu lệnh ConnectionString của tôi chỉ chạy được nếu máy bạn cài Office 2007 trở lên. Nếu 2003 thì phải dùng Jet OleDB
 

kieu manh

IIIIIIIIIIIIIIIII
Tham gia ngày
9 Tháng sáu 2012
Bài viết
3,616
Được thích
2,472
Điểm
560
Nơi ở
IIIIIIIIIIIIIIIII

Nguyễn Duy Tuân

Nghị Hách
Thành viên danh dự
Tham gia ngày
13 Tháng sáu 2006
Bài viết
4,224
Được thích
9,729
Điểm
860
Nơi ở
Hà Nội
Cũng có thử qua lại mấy cái đó rồi ... Nhưng Mình xài Office 2016x32
có lẻ nó thiếu cái gì đó ?!
Khai báo đúng như sau

Declare Function RunSQLToRange Lib "VBLibrary.dll" (ByVal ExcelPath As Variant, ByVal sSQL As Variant, ByVal Target As Variant) As Long

Có thêm “As Long” nhé. Mọi cái còn lại không sai đâu.
 

kieu manh

IIIIIIIIIIIIIIIII
Tham gia ngày
9 Tháng sáu 2012
Bài viết
3,616
Được thích
2,472
Điểm
560
Nơi ở
IIIIIIIIIIIIIIIII
Khai báo đúng như sau

Declare Function RunSQLToRange Lib "VBLibrary.dll" (ByVal ExcelPath As Variant, ByVal sSQL As Variant, ByVal Target As Variant) As Long

Có thêm “As Long” nhé. Mọi cái còn lại không sai đâu.
Cuối cùng Mình phải sửa code lại vầy nó Chạy rất nhanh ... thử 65536 dòng nó bay cái vèo
Code cũ
Mã:
qry.SQL.Text := sSQL;
Code mới thay thế
Mã:
qry.SQL.Text :=  'SELECT * FROM' + sSQL;
Với Mình ADO chỉ quan tâm 4 cái sau:
1/ Tạo kết nối với các CSDL
2/ Lấy dữ Liệu lên
3/ Ghi dữ liệu xuông
4/ lấy dữ liệu cho vào Mãng ... xong từ đó Cộng, trừ, nhân chia trong mãng .... Còn thuần ADO là thua mà ko dại gì lao vô đó mệt lăm
....
Cảm Ơn Bạn đã chỉ dẫn
 
Lần chỉnh sửa cuối:
Top Bottom