Đây là video hướng dẫn cách tạo DLL trên Delphi nhưng sử dụng trong VBA, Excel. Đây là phương pháp lập trình chuyên nghiệp nhưng không phải là khó. Giúp bạn bảo mật code của phần mềm tốt hơn.
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 ==========
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é.
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
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.
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.
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 ạ !
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ì đó.
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ì đó.
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.
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
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?
@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 !
@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;
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 !
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 !
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
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ự 1
Số thứ tự 2
Số thứ tự 3
Số thứ tự 4
Số thứ tự 5
Số thứ tự 6
Số thứ tự 7
Số thứ tự 8
Số thứ tự 9
Số thứ tự 10
Số thứ tự 11
Số thứ tự 12
Ví dụ
1
8
3
5
6
9
7
9
A
C
B
D
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 1
B
6 hoặc 2
C
7 hoặc 3
A
9 hoặc 4 hoặc 5 hoặc 0
D
Với ví dụ trên 18356979ACBD khi kiểm tra sẽ ra kết quả TRUE
Cảm ơn các bạn
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
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
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
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.
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.
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:
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:
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;
Đố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.
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;
Đố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 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;
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
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
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 ?!
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:
I have an Excel AddIn written in Delphi that has a VCL form with a TMemo on it. When I try to enter text into the Memo the input goes to Excel instead. When I start the form modal (ShowModal), all...
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:
I have an Excel AddIn written in Delphi that has a VCL form with a TMemo on it. When I try to enter text into the Memo the input goes to Excel instead. When I start the form modal (ShowModal), all...
- Đã 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.
- Đã 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.
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
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
#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
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.
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
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
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
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
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
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)
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
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
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ể
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
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
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
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
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.
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.
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;
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,...).