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

Liên hệ QC

Người dùng đang xem chủ đề này

Nguyễn Duy Tuân

Nghị Hách
Thành viên danh dự
Tham gia
13/6/06
Bài viết
4,841
Được thích
10,337
Giới tính
Nam
Nghề nghiệp
Giáo viên, CEO tại Bluesofts
Lần chỉnh sửa cuối:
Code với trả két ... chi phí mất thời gian quá
kể từ ngày biết viết cái Hàm kiểu 365 trên VBA ... sau gần 2 năm mới chuyển nó vào Delphi thành công
ko thể ngờ được nó đơn giản lắm chỉ có trên 10 dòng code thôi ... viết 1 cái Hàm chung nhất gán bất cứ 1 Array nào vào là ok

code ngắn lắm nó như sau.. Trong File có sử dụng code của @ThangCuAnh = Cảm ơn lắm lắm
Mã:
Rem https://youtu.be/XICP6C0yJQc
Declare PtrSafe Function ResizeArrayA Lib "MyLibrary64.dll" (ByVal arr As Variant) As Variant
Rem ==========
Function TransArray(ByVal rngIn As Range) As Variant
    Dim arr As Variant
    arr = rngIn.value
    TransArray = ResizeArrayA(arr)
End Function
Rem ==========
Function GetSQLArray(ByVal aPath As Variant, ByVal SQL As Variant) As Variant
    Dim hr As Long
    Dim arr As Variant, ArrDest As Variant
    Dim VB As New MyLibrary.VBLib                                   ''Check References ...MyLibrary64.dll
    arr = DataBaseToArray(aPath, SQL)
    Rem hr = FastTransArrayDirect(arr, ArrDest)                     ''Su dung ham API
    ArrDest = VB.TransposeArray(arr)                                ''Su dung COM
    If IsArray(ArrDest) Then GetSQLArray = ResizeArrayA(ArrDest)
End Function
Rem ========== Tao 1 mang voi so dong va cot tren Range
Function TaoArr(dong As Long, cot As Long) As Variant
    Rem Cu Phap: =TaoArr(10,10) Tao ra 10 dong x 10 cot
    Dim i As Long, J As Long
    ReDim arr(1 To dong, 1 To cot)
    For i = 1 To dong
        For J = 1 To cot
            arr(i, J) = i & "_" & J
        Next
    Next
    TaoArr = ResizeArrayA(arr)
End Function
Rem ==========
Video Demos
Liên kết: https://youtu.be/XICP6C0yJQc

Nếu không có nội dung bạn viết ở đây cùng video demo trên Youtube tại đó thi chắc tôi không quan tâm hàm của bạn làm gì cả. Điều duy nhất tôi chỉ muốn test nó làm đúng như video đó không mà thôi. Nếu không có hay có sự nhầm lẫn thì ta không nói nữa nhé.
 
Upvote 0
Mạnh cũng dễ thương lắm ... xong là thôi ... nghe lời cái anh kia cũng sẻ bớt bớt lại ... sẻ ko làm tổn thương ai nữa
trừ khi thấy nhột nhột thì cũng ấy thôi :p
 
Upvote 0
Gửi @Nguyễn Duy Tuân .... cái này là thiện ý vui vẻ he .... ko ai hack với hóc ở đây cả

nên làm thành sách và chỉ dẫn cái DLL như sau ... cho công chúng biết và cách sử dụng nó .... nếu thấy bài này thừa thì cho vào thùng RÁC ko sao cả he

1640401902563.png

Tải File đính kèm và xem
 

File đính kèm

Upvote 0
Gửi @Nguyễn Duy Tuân .... cái này là thiện ý vui vẻ he .... ko ai hack với hóc ở đây cả

nên làm thành sách và chỉ dẫn cái DLL như sau ... cho công chúng biết và cách sử dụng nó .... nếu thấy bài này thừa thì cho vào thùng RÁC ko sao cả he

View attachment 270743

Tải File đính kèm và xem

Tôi cũng muốn viết hướng dẫn chi tiết theo từng thành phần của các class trong addinatools.dll mà chưa làm được, phần cũng là chứ biết tools hỗ trợ. Hiện nay tôi chỉ tranh thủ tạo các clip hỗ trợ qua các ví dụ điển hình thôi còn tài liệu PDF hay viết lên website chưa làm được chi tiết.
Nếu có thể bạn chia sẻ tool để Reference như bạn làm thì việc tôi viết tài liệu sẽ đỡ mất nhiều time hơn.
 
Upvote 0
Các anh cho em hỏi chút về tham số mảng truyền từ VBA sang Delphi.
Bên Delphi em viết hàm TestArray như sau:
Mã:
function TestArray(Arr: array of integer): integer ; stdcall;
    var
        x, Tong : integer;
    begin
      Tong:=0;
        for x:= 0 to length(Arr)-1 do begin
            Tong:=Tong + Arr[x];
        end;
        Result := Tong;
    end;
Tham số của em là mảng số nguyên (Ở đây em làm ví dụ đơn giản để hiểu cách truyền tham số mảng), giờ bên VBA em viết lệnh như sau:
Mã:
Declare Function TestArray Lib "TestDLL.DLL" (ByVal Arr As Variant) As Integer

Public Sub Test()
    MsgBox TestArray(Array(1, 3))
End Sub
Nhưng lại không chạy được, Excel tắt luôn. Vậy code của em truyền như thế nào để delphi hiêu tham số Array, cảm ơn các anh trước.
 
Upvote 0
Chào Anh/Chị và các bạn !
Em đang tập chuyển các đoạn code từ VBA sang delphi. Em có chuyển được 1 vài đoạn code cơ bản, tuy nhiên nếu các đoạn code phức tạp thì khi viết e không kiểm soát hết lỗi, mặc dù Build ra DLL thì delphi vẫn cho thì khi đó viết hàm trên VBA nó đơ excel và thoát excel.
Anh/chị cho em hỏi là có cách nào mình 'test' nhanh code trên delphi trước khi build ra DLL không ạ ? (vì khi e viết trên VBA thì nếu có sai gì thì code tự động báo lỗi và chỉ ngay chỗ dòng sai, khi đó em biết e đang sai và sửa lại, còn từ delphi kéo qua VBA thì e không biết nó sai khúc nào, chỗ nào )
Em cảm ơn ạ !
 
Upvote 0
Chào Anh/Chị và các bạn !
Em đang tập chuyển các đoạn code từ VBA sang delphi. Em có chuyển được 1 vài đoạn code cơ bản, tuy nhiên nếu các đoạn code phức tạp thì khi viết e không kiểm soát hết lỗi, mặc dù Build ra DLL thì delphi vẫn cho thì khi đó viết hàm trên VBA nó đơ excel và thoát excel.
Anh/chị cho em hỏi là có cách nào mình 'test' nhanh code trên delphi trước khi build ra DLL không ạ ? (vì khi e viết trên VBA thì nếu có sai gì thì code tự động báo lỗi và chỉ ngay chỗ dòng sai, khi đó em biết e đang sai và sửa lại, còn từ delphi kéo qua VBA thì e không biết nó sai khúc nào, chỗ nào )
Em cảm ơn ạ !

Bạn học cách debug trong Delphi. Trong Delphi và menu "Run" -> Parameters.... Trong cửa sổ "Debugger" khai báo mục "Host Application", nhập đường dẫn Excel hay ứng dụng sử dụng DLL, ví dụ nhập C:\Program Files (x86)\Microsoft Office\root\Office16\Excel.exe
Từ bây giờ cứ khi muốn debug, bạn hãy đặt Breakpoint tại những dòng lệnh muốn kiểm tra, nhấn F9 để Delphi chạy host application và bạn có thể debug DLL hay thứ gì đó.
 
Upvote 0
Bạn học cách debug trong Delphi. Trong Delphi và menu "Run" -> Parameters.... Trong cửa sổ "Debugger" khai báo mục "Host Application", nhập đường dẫn Excel hay ứng dụng sử dụng DLL, ví dụ nhập C:\Program Files (x86)\Microsoft Office\root\Office16\Excel.exe
Từ bây giờ cứ khi muốn debug, bạn hãy đặt Breakpoint tại những dòng lệnh muốn kiểm tra, nhấn F9 để Delphi chạy host application và bạn có thể debug DLL hay thứ gì đó.
Em cảm ơn anh ạ !
 
Upvote 0

Thế thì khác gì lấy búa tự nện vào mặt ‍‍‍‍‍‍ ‍‍‍‍‍‍ ‍‍‍‍‍‍ trên bàn chân. :D :D

1687573454423.png

1687573418312.png

1687573447381.png

Kiếm đôi dép kê mông xem chương trình nghệ thuật nào.
 
Upvote 0
Upvote 0
viết bằng python và C# đi, giờ này làm gì còn ai dùng delphi nữa
Python bây giờ cũng dùng rất nhiều thư viện của C/C++ rồi, thơm lắm các bác ạ
 
Upvote 0
viết bằng python và C# đi, giờ này làm gì còn ai dùng delphi nữa
Python bây giờ cũng dùng rất nhiều thư viện của C/C++ rồi, thơm lắm các bác ạ

Mỗi ngôn ngữ, công cụ có cái đích của nó, có điểm chung, có điểm riêng, nhu cầu nào thì chọn ngôn ngữ, công cụ đó sao cho phù hợp nhất.
Còn riêng bài này bạn khuyên dùng Python và C# mà không nói mục đích, lý do vì sao thì người đọc khó mà ghi nhận. Bạn cần đưa ra lý do có tính so sánh không dùng Delphi so với Python, C# khi mục đích làm gì đó không?

Tôi nói luôn cho bạn nếu đóng gói thư viện ra DLL biên dịch mã máy, xuất hàm API thì dùng Delphi hay C++ là phù hợp nhất đấy nhé. Vì:
+ Biên dịch hoàn toàn ra mã máy - C# là thông dịch, không phải mã máy, Python có thể tạo nhưng rất phức tạp.
+ DLL, EXE tạo ra từ Delphi là độc lập, không cần cõng theo framework.NET hay bộ thư việc đi cùng nếu nó không liên kết tới một thư việc của bên thứ ba khác.
+ Tốc độ ứng dụng, các hàm trong DLL tạo ra từ Delphi, C++ là rất nhanh.

Chia sẻ thêm thông tin về Delphi: dùng để xây dựng các thư viện , các ứng dụng có giao diện rất dễ làm. Tạo các phần mềm chạy trên các nền tảng Windows, iOS, Android, Linux. Các platforms 32, 64-bit.

 
Lần chỉnh sửa cuối:
Upvote 0
python và C# dễ học, dễ debug hơn delphi, cộng đồng hỗ trợ cũng nhiều hơn
còn nếu viết dạng xử lý văn bản và excel thì nên viết trực tiếp thành ứng dụng, nó khá thuần và dễ chịu cho người viết.
Còn việc chạy trên nhiều nên tảng không còn là vấn đề với py và C# nữa rồi
delphi và C++ chỉ nên dùng khi viết các chương trình lớn
 
Upvote 0
python và C# dễ học, dễ debug hơn delphi, cộng đồng hỗ trợ cũng nhiều hơn
còn nếu viết dạng xử lý văn bản và excel thì nên viết trực tiếp thành ứng dụng, nó khá thuần và dễ chịu cho người viết.
Còn việc chạy trên nhiều nên tảng không còn là vấn đề với py và C# nữa rồi
delphi và C++ chỉ nên dùng khi viết các chương trình lớn

Dễ học vờ debug thì là nhận xét rất chủ quan. Là một công cụ lập trình thì debug là tối thiểu phải có, từ cách đây mấy chục năm Pascal, Delphi 1.0 đã debug rồi. Dễ học thì khó với người này lại dễ với người khác, nguồn tài liệu tiếng Anh thì nhiều vô kể. Và vấn đề dễ học hay không không phải lý do chính để bỏ ngôn ngữ này chọn ngôn ngữ kia mà là học để tạo ra cái gì.
Bạn tham gia vào chủ đề này có biết tôi nói về mục đích xây dựng DLL không? Có ví dụ rõ ràng để ứng dụng chạy trong Excel. Bạn bây giờ lại đổi sang nhận xét “chỉ nên dùng Delphi, C++ đêt tạo phần mềm lớn”. Quay lại nhận xét trước đó của bạn là “chuyển sang Python, C# bây giờ ai học Delphi”. Vậy cái bạn bảo chuyên sang đó làm DLL tốt hơn Delphi ở điểm nào?
 
Upvote 0
@Nguyễn Duy Tuân cho em hỏi là: Có cách nào từ trong hàm viết trên delphi mình gán mảng dữ liệu xuống excel không ạ ?
Em đang đi theo hướng viết hàm trong DLL trả về 1 mảng, rồi cho kết quả đó bằng với 1 mảng trên excel rồi mới dán xuống excel. E gửi đoạn code để a xem ạ . E có tìm hiểu thì thấy khởi tạo object: CreateOleObject('Excel.Application'), nhưng cái hàm ở các trang đầu a viết lấy dữ liệu dùng ADO thì không cần khởi tạo object nó vẫn dán kết quả xuống cells active trên excel. E cảm ơn a !z4459615254634_50c55f237f37d629381e89986ed1aa69.jpg
 
Upvote 0
@Nguyễn Duy Tuân cho em hỏi là: Có cách nào từ trong hàm viết trên delphi mình gán mảng dữ liệu xuống excel không ạ ?
Em đang đi theo hướng viết hàm trong DLL trả về 1 mảng, rồi cho kết quả đó bằng với 1 mảng trên excel rồi mới dán xuống excel. E gửi đoạn code để a xem ạ . E có tìm hiểu thì thấy khởi tạo object: CreateOleObject('Excel.Application'), nhưng cái hàm ở các trang đầu a viết lấy dữ liệu dùng ADO thì không cần khởi tạo object nó vẫn dán kết quả xuống cells active trên excel. E cảm ơn a !View attachment 291905

Không ai dùng CreateOleObject khi viết hàm trong DLL cả bạn nhé. Nếu có chỉ là khởi tạo Excel Application để test mà thôi.
Muốn tạo hàm KiemTraTTNH trả về array trong VBA thì bạn phải làm như sau

function KiemTraTTNH(Vung: OleVariant): OleVariant; stdcall;
begin
//Nếu là mảng 2D thì d1, d2 là vị trí dòng bắt đầu và dòng cuối của mảng; c1, c2 là vị trí cột đầu và cột cuối của mảng
Result := VarArrayCreate([d1, d2, c1, c2], varVariant);
//Nếu mảng 1D thì là: Result := VarArrayCreate([c1, c2], varVariant);
Bây giờ bạn chỉ cần làm việc gán các giá trị cho các phần từ mảng:
for I := d1 to d2 do
for J := c1 to c2 do
begin
Result[I, J] :=giá trị
end;
end;
 
Upvote 0
Dạ, tạo ra kết quả mảng 2D trên delphi thì e đã làm được, ý em là cái hàm mình truyền thêm 1 tham số "dán" kết quả mảng 2D này xuống sheet (ví dụ ô A1 )
function KiemTraTTNH(Vung: OleVariant; Range: OleVariant): OleVariant; stdcall;
.....
Range := Mảng kết quả 2D //ý e chỗ này mình dán cái mảng 2D xuống dưới excel tại vị trí mình truyền tham số trên hàm á anh
.....
End;
Cảm ơn anh !
 
Upvote 0
haha, tôi vẫn khuyên các bạn trẻ đừng học theo bác tuân, vài dòng code vba không có gì mà phải dùng đến delphi mà protect code đâu
 
Upvote 0
Dạ, tạo ra kết quả mảng 2D trên delphi thì e đã làm được, ý em là cái hàm mình truyền thêm 1 tham số "dán" kết quả mảng 2D này xuống sheet (ví dụ ô A1 )
function KiemTraTTNH(Vung: OleVariant; Range: OleVariant): OleVariant; stdcall;
.....
Range := Mảng kết quả 2D //ý e chỗ này mình dán cái mảng 2D xuống dưới excel tại vị trí mình truyền tham số trên hàm á anh
.....
End;
Cảm ơn anh !

Bạn tạo thêm tham số cho hàm để nhận Range từ VBA. Tham số này kiểu OleVariant cho dễ dùng. Trong hàm bạn dùng nó gần như ở VBA.
 
Lần chỉnh sửa cuối:
Upvote 0
khả năng có thể học được bất cứ ngôn ngữ hiện đại nào ngoài VBA thì điều tốt cả . nhưng cũng xác định mục đích rõ ràng của nó

chi tiết viết nó cho Excel VBA hay cái gì thì sẽ biết được nó có thực tế hay không còn cứ nói khơi khơi tốt mà không chỉ ra tốt trong trường hợp nào cảm giác thấy cào bằng tất cả

thực tế tôi thấy nếu có khả năng viết C/c++ Or Delphi viết 1 thư viện hàm DLL thật chuẩn xong có thể call nó từ nhiều ngôn ngữ khác nhau rất tốt
 
Lần chỉnh sửa cuối:
Upvote 0
Chào các bạn, tôi muốn viết một hàm kiểm tra logic trên Delphi trả về kết quả là TRUE hoặc FALSE, trong đó
Dãy ký tự cần kiểm tra gồm 12 ký tự (gồm cả số và chữ)
Ví dụ dãy số 18356979ACBD
Số thứ tự 1Số thứ tự 2Số thứ tự 3Số thứ tự 4Số thứ tự 5Số thứ tự 6Số thứ tự 7Số thứ tự 8Số thứ tự 9Số thứ tự 10Số thứ tự 11Số thứ tự 12
Ví dụ18356979ACBD
Nguyên tắc như sau
Số thứ tự 2 sẽ đối chiếu với Số thứ tự 11
Số thứ tự 5 sẽ đối chiếu với Số thứ tự 10
Số thứ tự 7 sẽ đối chiếu với Số thứ tự 9
Số thứ tự 8 sẽ đối chiếu với Số thứ tự 12

Nguyên tắc đổi sốKiểm tra đúng
8 hoặc 1B
6 hoặc 2C
7 hoặc 3A
9 hoặc 4 hoặc 5 hoặc 0D

Với ví dụ trên 18356979ACBD khi kiểm tra sẽ ra kết quả TRUE
Cảm ơn các bạn
 
Upvote 0
Chào các bạn, tôi muốn viết một hàm kiểm tra logic trên Delphi trả về kết quả là TRUE hoặc FALSE, trong đó
Dãy ký tự cần kiểm tra gồm 12 ký tự (gồm cả số và chữ)
Ví dụ dãy số 18356979ACBD

Với ví dụ trên 18356979ACBD khi kiểm tra sẽ ra kết quả TRUE
Cảm ơn các bạn

Nhìn có vẻ giống giải thuật mã hoá + mắm muối (salt) nhỉ :D
 
Upvote 0
nhiều thứ nếu keo tôi viết chưa biết khi nào xong

Rảnh tôi bà tám với con ChatGPT 1 chút nó lòi ra đầy thứ xong từ cái mớ cơ bản đó dò viết lại chút là xong thôi
 
Upvote 0
Mã:
uses
  System.SysUtils,
  System.Classes;

{$R *.res}
function test(a,b : Double):string ; stdcall
 Begin
   if a=b then Result := 'Bang Nhau' else
  Result := 'Khong Bang Nhau';
End;


begin
end.

Mình thử tạo cái hàm trên delphi, tuy nhiên thử kết nối với Excel thì chạy hàm trên Excel bị văng ra, xem giúp mình lỗi ở đâu, cảm ơn các bạn
 
Upvote 0
Mã:
uses
  System.SysUtils,
  System.Classes;

{$R *.res}
function test(a,b : Double):string ; stdcall
 Begin
   if a=b then Result := 'Bang Nhau' else
  Result := 'Khong Bang Nhau';
End;


begin
end.

Mình thử tạo cái hàm trên delphi, tuy nhiên thử kết nối với Excel thì chạy hàm trên Excel bị văng ra, xem giúp mình lỗi ở đâu, cảm ơn các bạn
Bạn đổi string thành OleVariant , trong VBA khai báo kiểu tương ứng là Variant là được.
 
Upvote 0
Code Delphi cái nào liên quan đến string thì coi bộ khó xơi, dễ bị im re hay tắt đột ngột lắm. Mà đặc biệt là gọi từ Excel, còn nếu viết DLL để gọi từ C# thì có nhiều cái để chọn ví dụ như PChar, PAnsiChar, WideString.
 
Upvote 0
Code Delphi cái nào liên quan đến string thì coi bộ khó xơi, dễ bị im re hay tắt đột ngột lắm. Mà đặc biệt là gọi từ Excel, còn nếu viết DLL để gọi từ C# thì có nhiều cái để chọn ví dụ như PChar, PAnsiChar, WideString.

Thực ra để tránh người mới học lập trình Delphi phải học những cái cao và trừu tượng nên mình cứ quy cho mọi người khai báo về OleVariant cho nó đơn giản. Mới học lập trình mà lao vào DLL thì cứ đơn giản để ra sản phẩm đã. Còn muốn dùng đúng kiểu dữ liệu là String trong mọi môi trường lập trình khác thì vẫn viết được trong DLL trong Delphi chạy tốt. Để làm điều này phải hiểu về con trỏ và cấp phát bộ nhớ, kiến thức này là hệ thống không chỉ Delphi mà C/C++ hay ngôn ngữ nào tạo ra cũng phải vậy.
 
Upvote 0
nhờ ACE giúp mình giải quyết vấn đề truyền chuỗi trên Range: Mục đích của hàm là nối 2 chuỗi lại với nhau thôi.
- Code delphi mình viết như sau
Mã:
library TryString64Bit;

uses
  System.SysUtils,
  System.Classes,Variants;

{$R *.res}
function ConcatStrings(str1, str2: oleVariant): oleVariant; stdcall;
var
  ResultString: STRING;
begin
  ResultString :=string(TVarData(str1).VOleStr) + string(TVarData(str2).VOleStr);
  Result := (ResultString);
end;
exports
  ConcatStrings;
begin

end.
- Code trong VBA mình truyền trực tiếp chuỗi vào thì hàm trả về đúng:
Mã:
Declare PtrSafe Function ConcatStrings Lib "D:\1. Delphi\Project\Learn\TryString64Bit\Win64\Debug\TryString64Bit.dll" (ByVal str1 As Variant, ByVal str2 As Variant) As Variant

Sub TestConcat()
    Dim result As String
    result = ConcatStrings("Hello ", "World")
    MsgBox result
End Sub
- Nhưng khi gõ ô A1 chữ "Hello " , và ô B1 chữ "World", ô C1 mình gọi hàm =ConcatStrings(A1; B1), thì báo lỗi như hình bên dưới, chỉ báo lỗi khi dùng excel 64bit còn 32bit thì thậm chí truyền trực tiếp không dùng Tvardata hàm vẫn chạy bình thường, mình nghĩ do excel 64bit truyền qua chính là range chữ ko phải string, Dòng báo lỗi là dòng này:
Mã:
ResultString :=string(TVarData(str1).VOleStr) + string(TVarData(str2).VOleStr);
1702440243229.png
 
Upvote 0
nhờ ACE giúp mình giải quyết vấn đề truyền chuỗi trên Range: Mục đích của hàm là nối 2 chuỗi lại với nhau thôi.
- Code delphi mình viết như sau
Mã:
library TryString64Bit;

uses
  System.SysUtils,
  System.Classes,Variants;

{$R *.res}
function ConcatStrings(str1, str2: oleVariant): oleVariant; stdcall;
var
  ResultString: STRING;
begin
  ResultString :=string(TVarData(str1).VOleStr) + string(TVarData(str2).VOleStr);
  Result := (ResultString);
end;
exports
  ConcatStrings;
begin

end.
- Code trong VBA mình truyền trực tiếp chuỗi vào thì hàm trả về đúng:
Mã:
Declare PtrSafe Function ConcatStrings Lib "D:\1. Delphi\Project\Learn\TryString64Bit\Win64\Debug\TryString64Bit.dll" (ByVal str1 As Variant, ByVal str2 As Variant) As Variant

Sub TestConcat()
    Dim result As String
    result = ConcatStrings("Hello ", "World")
    MsgBox result
End Sub
- Nhưng khi gõ ô A1 chữ "Hello " , và ô B1 chữ "World", ô C1 mình gọi hàm =ConcatStrings(A1; B1), thì báo lỗi như hình bên dưới, chỉ báo lỗi khi dùng excel 64bit còn 32bit thì thậm chí truyền trực tiếp không dùng Tvardata hàm vẫn chạy bình thường, mình nghĩ do excel 64bit truyền qua chính là range chữ ko phải string, Dòng báo lỗi là dòng này:
Mã:
ResultString :=string(TVarData(str1).VOleStr) + string(TVarData(str2).VOleStr);
View attachment 297534

Lý do lỗi là khi bạn dùng hàm trên Worksheet, bạn truyền tham số là Range chứ không phỉa là Value (như trong VBA). Và trong mã nguồn hàm ConcatStrings của bạn thì fix cứng các tham số đều là Value - string. Bạn cần phải xử lý tình huống kiểu dữ liệu truyền vào và convert giá trị ra Value trước khi concat. Hàm viết lại như sau:


Mã:
function ConcatStrings(str1, str2: oleVariant): oleVariant; stdcall;
begin
  if TVarData(str1).VType = varDispatch then
     str1 := str1.Value2;
  if TVarData(str2).VType = varDispatch then
     str2 := str2.Value2;
  Result := string(TVarData(str1).VOleStr) + string(TVarData(str2).VOleStr);
end;
 
Upvote 0
Em đã sửa như a gợi ý, nhưng vẫn bị lỗi
View attachment 297548

Đối với Excel 64-bit bạn không dùng trực tiếp hàm ở Declare trên worksheet được (dùng trực tiếp trong code VBA ok). Bạn phải viết một hàm khác để gọi nó:

Function UDF_ConcatStrings (ByVal str1 As String, ByVal str2 As String) As Variant
UDF_ConcatStrings := ConcatStrings(str1, str2)
End Function

Bây giờ trên worksheet bạn dùng hàm UDF_ConcatStrings là ok. Trong hàm UDF_ConcatStrings tôi đã đổi kiểu giá trị tham số từ Variant thành String nên giá trị tham số hàm này luôn là Value - String vì thế trong Delphi bạn có thể không cần bẫy kiểu:
if TVarData(str1).VType = varDispatch then
str1 := str1.Value2;

Nếu lập trình hàm UDF nâng cao - viết nhiều tình huống thì vẫn nên để kiểu tham số là Variant.
 
Upvote 0
Rảnh thử cái thấy chạy

1702471339706.png

Mã:
function ConcatStrings(const str1, str2: oleVariant): oleVariant; stdcall;
var
  tempStr1, tempStr2: oleVariant;
begin
  tempStr1 := str1;
  tempStr2 := str2;

  if TVarData(tempStr1).VType = varDispatch then
     tempStr1 := tempStr1.Value2;
  if TVarData(tempStr2).VType = varDispatch then
     tempStr2 := tempStr2.Value2;
  Result := string(TVarData(tempStr1).VOleStr) + string(TVarData(tempStr2).VOleStr);
end;
 
Upvote 0
Đối với Excel 64-bit bạn không dùng trực tiếp hàm ở Declare trên worksheet được (dùng trực tiếp trong code VBA ok). Bạn phải viết một hàm khác để gọi nó:
Rất cảm ơn anh, đây là nguyên nhân dẫn đến lỗi
Bài đã được tự động gộp:

Rảnh thử cái thấy chạy

View attachment 297556

Mã:
function ConcatStrings(const str1, str2: oleVariant): oleVariant; stdcall;
var
  tempStr1, tempStr2: oleVariant;
begin
  tempStr1 := str1;
  tempStr2 := str2;

  if TVarData(tempStr1).VType = varDispatch then
     tempStr1 := tempStr1.Value2;
  if TVarData(tempStr2).VType = varDispatch then
     tempStr2 := tempStr2.Value2;
  Result := string(TVarData(tempStr1).VOleStr) + string(TVarData(tempStr2).VOleStr);
end;
hàm đó mà viết trên worksheet thì bị lỗi anh
 
Upvote 0
thì bài 1435 chỉ cho cách viết trên Cells rồi còn gì ... qua hàm trung gian

Mã:
Function UDF_ConcatStrings (ByVal str1 As String, ByVal str2 As String) As Variant
UDF_ConcatStrings := ConcatStrings(str1, str2)
End Function

Cơ bản tham khảo thêm 1 cách viết và chạy ra kết quả còn thực tế ứng dụng thì tuỳ chỉnh
 
Upvote 0
chỉnh nhẹ cái dùng cả 2 thôi

1702473957857.png

Khi viết xong phá các kiểu xem .. tiếng Việt, tiếng nhật + vvv

1702474264025.png
 
Lần chỉnh sửa cuối:
Upvote 0
Mấy năm trước có hỏi anh tây là Delphi có viết được COM ActiveX Exe hay không
trả lời: Bất cứ ngôn ngữ lập trình nào có hổ trợ viết COM cho Windows thì điều viết tốt COM ActiveX Exe ... còn chi tiết sao nó không nói :p

1/ trên VB6 ta viết COM ActiveX Exe quá đơn giản vì bản thân nó có sẳn viết xong dùng chung cho 32 và 64 bit ( chỉ 1 File duy nhất )
Bản chất cái ruột của nó cũng chỉ là 32 bit

2/ trên Delphi cũng như trên ta viết 1 COM ActiveX Exe xong cũng dùng chung cho 32 và 64 bít ( chỉ 1 File duy nhất )

Nhưng COM ActiveX Exe viết trên Delphi rõ nét 32 bit và 64 bit khi builder nó .. Tốt nhất Builder 64 bit .
còn VB6 bản chất vẫn chỉ là 32 bít

3/ thấy python cũng viết nhưng kiểu đóng gói 1 mớ file vào đó xong khi chạy xả nén vào đâu đó trên PC xong load hàm ( 1 mớ File )

4/ Còn VB.NET, C# và C/c++ chưa thấy hay họ chưa viết ???!!!


trong 1 số trường hợp có thể viết COM ActiveX Exe sử dụng chung cho 32 và 64 bít thấy cũng hay ho

Viết COM ActiveX Exe như vậy khỏi mất công khai báo API 32 và 64 bit cũng tiện --=0

Gợi ý cho ai đó tò mò lý sự tiếp nè ... Tại sao Windows lại không nhận diện hay phân biệt COM
ActiveX Exe là 32 hay 64 bit ?!
 
Lần chỉnh sửa cuối:
Upvote 0
Có 1 vấn đề liên quan đến việc gọi form trong Delphi mình đã tìm hiểu nhiều chỗ nhưng không giải quyết được nhờ ACE giúp đỡ:

Mã:
Procedure OpenFormMain();stdcall;
var
  frm:TfrmMain;
begin
  frm:=TfrmMain.Create(nil);
  //frm.Showmodal;
  frm.Show;
end;

khi excel gọi form trong delphi, vì muốn vừa tương tác được trên form và cũng có thể click chọn các ô trên sheet nên mình dùng frm.Show, khi đó trên Form mình có 1 TEdti, khi click vào đó nhập dữ liệu thi chữ sẽ được đánh vào Activecell trong excel chứ không đánh vào Tedit trên form, nếu dùng frm.Showmodal thì sẽ nhập được trên form nhưng lại không thao tác được với các ô trên sheet. Mình có tìm hiểu thì cũng nhiều chỗ bị giống vầy, mà cách họ đưa ra vẫn chưa biết cách áp dụng:
 
Upvote 0
Có 1 vấn đề liên quan đến việc gọi form trong Delphi mình đã tìm hiểu nhiều chỗ nhưng không giải quyết được nhờ ACE giúp đỡ:

Mã:
Procedure OpenFormMain();stdcall;
var
  frm:TfrmMain;
begin
  frm:=TfrmMain.Create(nil);
  //frm.Showmodal;
  frm.Show;
end;

khi excel gọi form trong delphi, vì muốn vừa tương tác được trên form và cũng có thể click chọn các ô trên sheet nên mình dùng frm.Show, khi đó trên Form mình có 1 TEdti, khi click vào đó nhập dữ liệu thi chữ sẽ được đánh vào Activecell trong excel chứ không đánh vào Tedit trên form, nếu dùng frm.Showmodal thì sẽ nhập được trên form nhưng lại không thao tác được với các ô trên sheet. Mình có tìm hiểu thì cũng nhiều chỗ bị giống vầy, mà cách họ đưa ra vẫn chưa biết cách áp dụng:
đang rảnh bà tám chút xong tự dò nha

trang này là trang 73 thì dò ngược lại từ trang 72,71.... tới khi thấy bài đó thì dửng lại xong tải về xem lại xem xong tính tiếp

có thể sẻ có nhiều cách xử lý khác nhau .. nhưng code két phải nên thử nhiều cách xong chọn lấy 1 cách phù hợp mà sử dụng

vài năm trước thớt này có rồi ................. cảm giác như đang bắt đầu dò học Delphi
 
Lần chỉnh sửa cuối:
Upvote 0
đang rảnh bà tám chút xong tự dò nha

trang này là trang 73 thì dò ngược lại từ trang 72,71.... tới khi thấy bài đó thì dửng lại xong tải về xem lại xem xong tính tiếp

có thể sẻ có nhiều cách xử lý khác nhau .. nhưng code két phải nên thử nhiều cách xong chọn lấy 1 cách phù hợp mà sử dụng

vài năm trước thớt này có rồi ................. cảm giác như đang bắt đầu dò học Delphi
- Đã dò ngược lại đến trang 65 vẫn ko thấy video như a nói ( ko biết a có hiểu lằm ý câu hỏi không)
- Delphi là ngôn ngữ khó, ko dễ mò như vba nên khi đụng vấn đề khó search ko giải quyết được, hỏi cũng ko ai trả lời thì tạm thời cất đó, vài năm sau khi nào fix đc vấn đề lại quay lại mò tiếp thôi. Số lần cất đi làm lại cũng khoảng 20 lần, số năm mò nó cũng gần chục, tìm hiểu delphi vì đam mê và cũng giải trí thôi chứ chưa mang lại giá trị vật chất cho bản thân.
 
Upvote 0
- Đã dò ngược lại đến trang 65 vẫn ko thấy video như a nói ( ko biết a có hiểu lằm ý câu hỏi không)
- Delphi là ngôn ngữ khó, ko dễ mò như vba nên khi đụng vấn đề khó search ko giải quyết được, hỏi cũng ko ai trả lời thì tạm thời cất đó, vài năm sau khi nào fix đc vấn đề lại quay lại mò tiếp thôi. Số lần cất đi làm lại cũng khoảng 20 lần, số năm mò nó cũng gần chục, tìm hiểu delphi vì đam mê và cũng giải trí thôi chứ chưa mang lại giá trị vật chất cho bản thân.
đoán chút xem sao khi nào rảnh xem lại ... có lẻ bài đó 2 ý

1/ là gõ trên Form

2/ là khi gõ vào TEdti thì chữ trên TEdti sẻ cho xuống Cells

thử xem

Mã:
Excel.ActiveCell.Value2 :=TEdti.Text
 
Upvote 0
Code delphi gọi form e viết như sau
Mã:
library FormTypingError;
uses
  System.SysUtils,
  System.Classes,
  frmInput in 'frmInput.pas' {Form1};

{$R *.res}
procedure OpenFormInput();stdcall;
var
  frm:TForm1;
begin
  frm:=TForm1.Create(nil);
  frm.show;
end;
exports
  OpenFormInput;
begin
end.

trên form thêm vào 1 tedit và 1 tbutton
1704551556484.png
code show form trên VBA
Mã:
#If Win64 Then
Private Declare PtrSafe Sub OpenFormInput Lib "FormTypingError64.dll" ()
#Else
Private Declare PtrSafe Sub OpenFormInput Lib "FormTypingError.dll" ()
#End If

Sub OpenFormDelphi()
    OpenFormInput
End Sub

Khi form được mở lên, như này, ta bấm vào tedit nhập dữ liệu thì chữ nhập từ bàn phím nó lại nhảy xuống ô activecell mà không được nhập lên tedit
1704551893880.png
 

File đính kèm

Upvote 0
Code delphi gọi form e viết như sau
Mã:
library FormTypingError;
uses
  System.SysUtils,
  System.Classes,
  frmInput in 'frmInput.pas' {Form1};

{$R *.res}
procedure OpenFormInput();stdcall;
var
  frm:TForm1;
begin
  frm:=TForm1.Create(nil);
  frm.show;
end;
exports
  OpenFormInput;
begin
end.

trên form thêm vào 1 tedit và 1 tbutton
View attachment 298142
code show form trên VBA
Mã:
#If Win64 Then
Private Declare PtrSafe Sub OpenFormInput Lib "FormTypingError64.dll" ()
#Else
Private Declare PtrSafe Sub OpenFormInput Lib "FormTypingError.dll" ()
#End If

Sub OpenFormDelphi()
    OpenFormInput
End Sub

Khi form được mở lên, như này, ta bấm vào tedit nhập dữ liệu thì chữ nhập từ bàn phím nó lại nhảy xuống ô activecell mà không được nhập lên tedit
View attachment 298143
1/ Nhắc lại bài số 1442 có rồi ... tìm lại là thấy vì nó còn liên quan các bài trước và sau đó ... để cho tìm xem các bài phát sinh quanh nó mới biết cách xử lý

2/ Mới xem file có virus Windows xoá ngay và luôn .... thôi không dính vào nữa hãy dò xem vì dính virus 1 lần đủ nhớ rồi
 
Lần chỉnh sửa cuối:
Upvote 0
trong file đính kèm có 3 file, 1 file excel và 2 file dll 1 file cho 32bit và 1 file code 64bit , đây là kết quả quét file excel và 2 file dll , file dll xuất từ delphi chỉ mấy dòng code bên trên.
1704596879459.png
1704597015326.png

1704597114110.png
 
Upvote 0
trong file đính kèm có 3 file, 1 file excel và 2 file dll 1 file cho 32bit và 1 file code 64bit , đây là kết quả quét file excel và 2 file dll , file dll xuất từ delphi chỉ mấy dòng code bên trên.
View attachment 298153
View attachment 298155

View attachment 298156
nó lại không xoá 2 cái DLL mà là xoá bay ngay cái file Excel ấy

Khi xoá xong file Excel hình như Windows nhận diện ra cứ tải file là xoá tiếp

1704597687801.png
 
Upvote 0
Delphi không quá khó học như c/c++ đâu ... chịu khó cày qua cái cửa khai báo và sử dụng là viết mã ầm ầm thôi

bên cạnh đó cần chút tư duy logis lắp ghép là xong :p:D

trích dẫn lại bài số 1440 khi tôi hỏi tây họ chỉ cho như hình sau ... còn lại do ta tự thân mà suy nghĩ vậy

1704681787373.png

thời điểm hiện tại không quá khó để viết mã Delphi vì mọi cái cơ bản đã có Em ChatGPT lo cho 1 phần nào đó ...
còn ta có biết vận dụng hay không là câu chuyện của chính ta _)()(-
 
Lần chỉnh sửa cuối:
Upvote 0
Lưu ý các bạn khi hỏi bài thì nên gửi mã nguồn test nhé.
 
Upvote 0
Delphi không quá khó học như c/c++ đâu ... chịu khó cày qua cái cửa khai báo và sử dụng là viết mã ầm ầm thôi

bên cạnh đó cần chút tư duy logis lắp ghép là xong :p:D

trích dẫn lại bài số 1440 khi tôi hỏi tây họ chỉ cho như hình sau ... còn lại do ta tự thân mà suy nghĩ vậy

View attachment 298183

thời điểm hiện tại không quá khó để viết mã Delphi vì mọi cái cơ bản đã có Em ChatGPT lo cho 1 phần nào đó ...
còn ta có biết vận dụng hay không là câu chuyện của chính ta _)()(-
Cái hình này không liên quan gì tới câu hỏi a, cố tình viết sang dll để hạn chế tối đa các trình diệt virus, nên ko có nhu cầu viết activexEXE
Lưu ý các bạn khi hỏi bài thì nên gửi mã nguồn test nhé.
bài 1.445 e đã ghi chi tiết các code thực hiện ra rồi đó a, và có cả file đính kèm. Mong muốn đơn giản chỉ là bấm nút trên excel sẽ hiện form delphi lên và có thể đánh chữ vào trong tedit của form Delphi ( nếu form Delphi chọn frm.Showmodal thì đánh chữ được còn frm.show thì không được)
 
Upvote 0
Cái hình này không liên quan gì tới câu hỏi a, cố tình viết sang dll để hạn chế tối đa các trình diệt virus, nên ko có nhu cầu viết activexEXE

bài 1.445 e đã ghi chi tiết các code thực hiện ra rồi đó a, và có cả file đính kèm. Mong muốn đơn giản chỉ là bấm nút trên excel sẽ hiện form delphi lên và có thể đánh chữ vào trong tedit của form Delphi ( nếu form Delphi chọn frm.Showmodal thì đánh chữ được còn frm.show thì không được)

1/ Bài số 1442 tôi keo tìm ngược lại thì không chịu tìm ... thớt này đến bài này mới có 73 trang thôi
2/ Bài số 1446 tôi nhắc lại phóng chữ to ra cũng không chịu tìm
3/ Nhắc lại lần 3 kèm theo hình xong tìm đi vì nó liên quan các bài trước và sau đó ....

xong khi tải về kiểu gì cũng hỏi tiếp nữa chắc chắn luôn. nên tôi cố tình để cho tìm xong hỏi lại các kiếm thức liên quan các bài liền kề trước và sau đó thì mới có khả năng viết tiếp được

xem hình xong tự hình dung ra mấy năm trước tôi hỏi bài khi gõ lên Edit1 xong nó nhảy xuống ô A1

1705020424096.png
 
Upvote 0
1/ Bài số 1442 tôi keo tìm ngược lại thì không chịu tìm ... thớt này đến bài này mới có 73 trang thôi
2/ Bài số 1446 tôi nhắc lại phóng chữ to ra cũng không chịu tìm
3/ Nhắc lại lần 3 kèm theo hình xong tìm đi vì nó liên quan các bài trước và sau đó ....

xong khi tải về kiểu gì cũng hỏi tiếp nữa chắc chắn luôn. nên tôi cố tình để cho tìm xong hỏi lại các kiếm thức liên quan các bài liền kề trước và sau đó thì mới có khả năng viết tiếp được

xem hình xong tự hình dung ra mấy năm trước tôi hỏi bài khi gõ lên Edit1 xong nó nhảy xuống ô A1

View attachment 298355
cám ơn a, nó nằm ở trang 58.
 
Upvote 0
đang viết Taskpane dính cái lỗi gõ lên TEdit nó xuống Range nè ... có vẻ Form DLL xử lý dễ hơn TaskPane

Chuột ở Ô nào thì nó xuống ngay Ô đó ... hình dưới là vị trí chuột tại A1 thì nó nhảy xuống A1

Untitled.png
 
Upvote 0
rảnh dò chơi với Em Chat mất buổi sáng ra cái Tô màu khi chọn Ô trên StringGrid
Delphi có đủ đồ chơi + Em ChatGPT code két nó trở nên đơn giản và từ không thể biến nó thành có thể _+)(9

các bạn trẻ có đam mê code két thì chịu khó dò với Em ChatGPT một chút là xong thôi _)()(---=0

1707189684523.png
 
Upvote 0
Trên Delphi có sẳn DBGrid StringGrid

1/ DBGrid hổ trợ nhiều thứ và truy xuất dữ liệu nhanh gấp vài lần StringGrid

2/ StringGrid chậm chạp và phổ thông ai cũng có thể dùng được mà không mất quá nhiều thời gian xử lý Unicode

3/ Muốn nhanh thì DBGrid là lựa chọn tốt hơn nhưng rất khó xử lý Unicode và lỗi WIDEMEMO trên DBGrid

Thời đại Al mọi cái biết chút tư duy logis có Em ChatGPT gợi ý cho xử lý loanh quanh vài ngày là xong

DBGrid Unicode và HighLight DBGrid
1718157990674.png
Các Bạn trẻ có đam mê code két chịu khó cùng Em ChatGPT dò chút là ra thôi
 
Upvote 0
kỳ nay Tôi đang rảnh và nổi gió ... ai muốn test thử ứng dụng gì úp lên đây Tôi test cho thoả mãn 2 điều kiện sau

1/ tải về không bị chặn và xoá bởi trình diệt virus

2/ không đóng gói cài đặt mà phơi bày DLL hay các thư viện liên quan ra đó ... rất thật và thực tế phơi bày ra như vậy

đóng gói làm trình cài đặt nhiều khi chứa đầy rác trong đó làm bẩn máy ra khi không sử dụng nữa ... trừ ứng dụng cần thuyết phải cài và không thể khác được như Bộ Office của Ms chẳng hạn :p:p


3/ khả năng test code của tôi rất tốt đấy ... nếu phát hiện lỗi trong trường hợp xx nào đó tôi sẻ mô ta cho mà Fix
 
Upvote 0
Các bác xem giúp!, bài học delphi đầu tiên của em , kết quả nhận được là 1 ký tự 'H' thay vì 1 string. hỏi con chatGPT nó hướng dẩn phương pháp này nọ, vẩn bị lổi.

code delphi :

library myDLL;

uses
SysUtils, Windows, ActiveX;

{$R *.res}


function HelloWorld: PWideChar; stdcall;
begin
Result := SysAllocString(PWideChar(WideString('Hello from Delphi DLL!')));
end;


procedure FreeString(Str: PWideChar); stdcall;
begin
SysFreeString(Str);
end;

exports
HelloWorld,
FreeString;

begin
end.
---------------------------
dùng vba :

Declare PtrSafe Function HelloWorld Lib "D:\Excel\Delphi\Win32\Debug\myDLL.dll" () As String
Declare PtrSafe Sub FreeString Lib "D:\Excel\Delphi\Win32\Debug\myDLL.dll" (ByVal Str As String)

Sub TestDLL2()
Dim result As String
result = HelloWorld()
MsgBox result
FreeString result
End Sub
 
Upvote 0
Các bác xem giúp!, bài học delphi đầu tiên của em , kết quả nhận được là 1 ký tự 'H' thay vì 1 string. hỏi con chatGPT nó hướng dẩn phương pháp này nọ, vẩn bị lổi.

code delphi :

library myDLL;

uses
SysUtils, Windows, ActiveX;

{$R *.res}


function HelloWorld: PWideChar; stdcall;
begin
Result := SysAllocString(PWideChar(WideString('Hello from Delphi DLL!')));
end;


procedure FreeString(Str: PWideChar); stdcall;
begin
SysFreeString(Str);
end;

exports
HelloWorld,
FreeString;

begin
end.
---------------------------
dùng vba :

Declare PtrSafe Function HelloWorld Lib "D:\Excel\Delphi\Win32\Debug\myDLL.dll" () As String
Declare PtrSafe Sub FreeString Lib "D:\Excel\Delphi\Win32\Debug\myDLL.dll" (ByVal Str As String)

Sub TestDLL2()
Dim result As String
result = HelloWorld()
MsgBox result
FreeString result
End Sub

Về chuyên sâu thì có những lý do và hoàn toàn xử lý vấn đề này tốt. Tuy nhiên với những người mới học Delphi mình không hướng dẫn cách đó bây giờ. Hiện tại tôi chia sẻ cách đơn giản mà chạy bình thường là:

Hàm dưới đây thay thế khai báo PWideChar thành OleVariant. Bên VBA/VB6 tương đương là VARIANT. .NET là Object.

function HelloWorld: PWideChar; stdcall;
begin
Result := SysAllocString(PWideChar('Hello from Delphi DLL!'));
end;

Đổi thành
function HelloWorld: OleVariant; stdcall;
begin
Result := SysAllocString(PWideChar('Hello from Delphi DLL!'));
end;

VBA khái báo sửa kiểu dữ liệu thành
Declare PtrSafe Function HelloWorld Lib "D:\Excel\Delphi\Win32\Debug\myDLL.dll" () As Variant

Lưu ý. Dữ liệu này dùng ở môi trường ngoài như VBA/VB6, .NET không phải giải phóng bộ nhớ vì môi trường đói nó tự giải phóng cho rồi vì thế không cần chạy hàm FreeString. Chỉ những công việc dùng nội tại trong Delphi mới phải giải phóng bộ nhớ nếu trước đó có xin cấp phát.
 
Upvote 0
Về chuyên sâu thì có những lý do và hoàn toàn xử lý vấn đề này tốt. Tuy nhiên với những người mới học Delphi mình không hướng dẫn cách đó bây giờ. Hiện tại tôi chia sẻ cách đơn giản mà chạy bình thường là:

Hàm dưới đây thay thế khai báo PWideChar thành OleVariant. Bên VBA/VB6 tương đương là VARIANT. .NET là Object.

function HelloWorld: PWideChar; stdcall;
begin
Result := SysAllocString(PWideChar('Hello from Delphi DLL!'));
end;

Đổi thành
function HelloWorld: OleVariant; stdcall;
begin
Result := SysAllocString(PWideChar('Hello from Delphi DLL!'));
end;

VBA khái báo sửa kiểu dữ liệu thành
Declare PtrSafe Function HelloWorld Lib "D:\Excel\Delphi\Win32\Debug\myDLL.dll" () As Variant

Lưu ý. Dữ liệu này dùng ở môi trường ngoài như VBA/VB6, .NET không phải giải phóng bộ nhớ vì môi trường đói nó tự giải phóng cho rồi vì thế không cần chạy hàm FreeString. Chỉ những công việc dùng nội tại trong Delphi mới phải giải phóng bộ nhớ nếu trước đó có xin cấp phát.

Cám ơn anh Tuân đã phản hồi,

Delphi báo lổi thế này :
1743153504081.png
 
Upvote 0
Upvote 0
Cho mình hỏi code sau có thể thêm module mới vào file excel khi không có module nào bị ẩn nhưng nếu workbook chứa module ẩn thị bị lỗi vậy làm sao khắc phục trong trường hợp lỗi này ?
Mã:
procedure AddVBAModule(const ExcelFilePath: string);
var
  ExcelApp, Workbook, VBProject, VBComponents, VBComponent: OleVariant;
begin
  try
    if not FileExists(ExcelFilePath) then
    begin
      ShowMessage('File not found: ' + ExcelFilePath);
      Exit;
    end;

    ExcelApp := CreateOleObject('Excel.Application');
    ExcelApp.Visible := False;
    ExcelApp.DisplayAlerts := False;

    Workbook := ExcelApp.Workbooks.Open(ExcelFilePath);

    // Check if access is allowed to VBProject
    try
      VBProject := Workbook.VBProject;
      VBComponents := VBProject.VBComponents;
    except
      on E: Exception do
      begin
        ShowMessage('Access to VBA project failed.' + sLineBreak +
                    'Make sure Excel trust settings allow access to VBA project object model.');
        ExcelApp.Quit;
        Exit;
      end;
    end;

    // Add module
    try
      VBComponent := VBComponents.Add(1); // 1 = vbext_ct_StdModule
     // VBComponent.Name := 'chinhhoang';
      VBComponent.CodeModule.AddFromString(
        'Sub HelloWorld()' + sLineBreak +
        '    MsgBox "Hello from Delphi!"' + sLineBreak +
        'End Sub');
    Workbook.Save;
    ShowMessage('Module added successfully.');
    except
      on E: Exception do
        ShowMessage('Error adding module: ' + E.Message);
    end;
    Workbook.Close(False);
    ExcelApp.Quit;
  except
    on E: Exception do
      ShowMessage('Error: ' + E.Message);
  end;
end;
 
Upvote 0
Cho mình hỏi code sau có thể thêm module mới vào file excel khi không có module nào bị ẩn nhưng nếu workbook chứa module ẩn thị bị lỗi vậy làm sao khắc phục trong trường hợp lỗi này ?
Mã:
procedure AddVBAModule(const ExcelFilePath: string);
var
  ExcelApp, Workbook, VBProject, VBComponents, VBComponent: OleVariant;
begin
  try
    if not FileExists(ExcelFilePath) then
    begin
      ShowMessage('File not found: ' + ExcelFilePath);
      Exit;
    end;

    ExcelApp := CreateOleObject('Excel.Application');
    ExcelApp.Visible := False;
    ExcelApp.DisplayAlerts := False;

    Workbook := ExcelApp.Workbooks.Open(ExcelFilePath);

    // Check if access is allowed to VBProject
    try
      VBProject := Workbook.VBProject;
      VBComponents := VBProject.VBComponents;
    except
      on E: Exception do
      begin
        ShowMessage('Access to VBA project failed.' + sLineBreak +
                    'Make sure Excel trust settings allow access to VBA project object model.');
        ExcelApp.Quit;
        Exit;
      end;
    end;

    // Add module
    try
      VBComponent := VBComponents.Add(1); // 1 = vbext_ct_StdModule
     // VBComponent.Name := 'chinhhoang';
      VBComponent.CodeModule.AddFromString(
        'Sub HelloWorld()' + sLineBreak +
        '    MsgBox "Hello from Delphi!"' + sLineBreak +
        'End Sub');
    Workbook.Save;
    ShowMessage('Module added successfully.');
    except
      on E: Exception do
        ShowMessage('Error adding module: ' + E.Message);
    end;
    Workbook.Close(False);
    ExcelApp.Quit;
  except
    on E: Exception do
      ShowMessage('Error: ' + E.Message);
  end;
end;

Theo kinh nghiệm của tôi thì code mà can thiệp vào đối tượng VBProject thì file phải không bị VBA Protection (không đặt mật khẩu VBA) và không bị can thiệp "phá" để ẩn hay làm gì đó liên quan đến cấu trúc VBComponents (module, class, Userform,...).
 
Upvote 0

Bài viết mới nhất

Back
Top Bottom