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

Liên hệ QC

Nguyễn Duy Tuân

Nghị Hách
Thành viên danh dự
Tham gia
13/6/06
Bài viết
4,649
Được thích
10,138
Giới tính
Nam
Nghề nghiệp
Giáo viên, CEO tại Bluesofts
Lần chỉnh sửa cuối:
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
Web KT
Back
Top Bottom