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:
Thầy cho e xin công thức tính trên excel ra kq như này với.
Lần sau thì mở chủ đề mới ở mục thích hợp nhé. Vấn đề của bạn đâu phải là Lập trình DLL?

Do tôi không dùng cách nối chuỗi mà dùng các phép toán số học nên chỉ phục vụ số xuất phát có nhiều nhất là 15 chữ số.

congdon.JPG

Nếu số chữ số là lớn tùy ý (nhập ở dạng text có độ lớn > 15) thì dùng hàm TEXTJOIN (hình như với Excel >= 2019). Lúc đó sử dụng mảng 1 từ công thức ở trên (công thức ở trên có 2 mảng). Nếu số chữ số > 15 và Excel < 2019 thì nên dùng hàm nối chuỗi tự tạo.
 
Lần chỉnh sửa cuối:
Upvote 0
Lâu lắm ko học bài ...nhờ các bạn chỉ dùm
VD: Trong VB6 mình khai báo như sau:
Mã:
Private ExcelApp As New Excel.Application
Public Property Get Application() As Excel.Application
    Set Application = ExcelApp
End Property
vậy mình muốn hỏi trong Delphi Mình khai báo tương đương code trên như thế nào để sử dụng tốt như code trên vb6 .... Mong chỉ dùm
Xin cảm ơn

Bạn viết một procedure và export từ dll ra.

var MyApp: OleVariant;
....
procedure GetApp(YourApp: IDispatch); stdcall;
begin
MyApp := YourApp;
end;

exports
GetApp;

Khi bạn declare bên VBA thìđổi function thành Sub.
 
Upvote 0
Lần sau thì mở chủ đề mới ở mục thích hợp nhé. Vấn đề của bạn đâu phải là Lập trình DLL?

Do tôi không dùng cách nối chuỗi mà dùng các phép toán số học nên chỉ phục vụ số xuất phát có nhiều nhất là 15 chữ số.

View attachment 229489

Nếu số chữ số là lớn tùy ý (nhập ở dạng text có độ lớn > 15) thì dùng hàm TEXTJOIN (hình như với Excel >= 2019). Lúc đó sử dụng mảng 1 từ công thức ở trên (công thức ở trên có 2 mảng). Nếu số chữ số > 15 và Excel < 2019 thì nên dùng hàm nối chuỗi tự tạo.
Anh @batman1 chỉ em cách copy Array bằng Api mà Sizeof(variant) trong Delphi đi anh
 
Upvote 0
Lần sau thì mở chủ đề mới ở mục thích hợp nhé. Vấn đề của bạn đâu phải là Lập trình DLL?

Do tôi không dùng cách nối chuỗi mà dùng các phép toán số học nên chỉ phục vụ số xuất phát có nhiều nhất là 15 chữ số.

View attachment 229489

Nếu số chữ số là lớn tùy ý (nhập ở dạng text có độ lớn > 15) thì dùng hàm TEXTJOIN (hình như với Excel >= 2019). Lúc đó sử dụng mảng 1 từ công thức ở trên (công thức ở trên có 2 mảng). Nếu số chữ số > 15 và Excel < 2019 thì nên dùng hàm nối chuỗi tự tạo.
Dạ! E cảm ơn thầy ạ! Vì e là thành viên mới nên ko rõ. Thầy thông cảm, chúc thầy mạnh khoẻ, công tác tốt ạ.
 
Upvote 0
Anh @batman1 chỉ em cách copy Array bằng Api mà Sizeof(variant) trong Delphi đi anh
Tôi ngán Delphi rồi. Thực ra cái tôi đam mê là Windows API. Delphi chỉ là mượn môi trường lập trình. Bây giờ tôi có cài Delphi nữa đâu.

Chủ đề này Tuân mở ra thì bạn hỏi Tuân là đúng người.
 
Upvote 0
Tôi ngán Delphi rồi. Thực ra cái tôi đam mê là Windows API. Delphi chỉ là mượn môi trường lập trình. Bây giờ tôi có cài Delphi nữa đâu.

Chủ đề này Tuân mở ra thì bạn hỏi Tuân là đúng người.
(@$%@
Mã:
    mSize:=Count * SizeOf(Variant);
    Move(inArrayByte^, Pointer(OutArray[0])^,  mSize);
Em Chạy xong là nó Lỗi thoát Fom luôn
 
Lần chỉnh sửa cuối:
Upvote 0
(@$%@
Mã:
    mSize:=Count * SizeOf(Variant);
    Move(inArrayByte^, Pointer(OutArray[0])^,  mSize);
Em Chạy xong là nó Lỗi thoát Fom luôn
Bạn và kieu manh có thói quen chỉ tung lên 1 dòng code nên rất khó để đoán. Trong trường hợp này tôi chỉ đoán là vd. inArrayByte là mảng BAI. Nó có là Pointer đâu mà inArrayByte^

Chưa tính tới mảng Variant. Tôi không biết inArrayByte mặt mũi thế nào nhưng Variant là cả một record. Có trường trong đó có thể là string, numeric, object, interface. Vậy thì chưa biết mảng inArrayByte thế nào thì khi copy sang OutArray thì giá trị của trường kia sẽ thế nào? Nó có là interface không, nếu phải thì interface ấy có tồn tại không. Nếu không tồn tại thì tiếp theo truy cập tới interface ấy sẽ có kết quả là "một nhát dao vào lưng".

Mà thôi, không quan trọng chuyện cụ thể như thế nào vì có nhìn được đoạn trước đâu để mà biết 2 mảng kia thế nào. Nhưng chắc chắn là ngoài lỗi inArrayByte^ còn có lỗi khác.

Theo tôi:
- không phải là inArrayByte^ mà là inArrayByte

- hoặc đơn giản là OutArray, hoặc cùng lắm là Pointer(OutArray[0]). Không phải là Pointer(OutArray[0])^

Đấy là nếu tôi còn nhớ đúng. Tôi đã nói rồi, bạn hãy hỏi Tuân vì tôi không cài Delphi.
 
Upvote 0
Bạn và kieu manh có thói quen chỉ tung lên 1 dòng code nên rất khó để đoán. Trong trường hợp này tôi chỉ đoán là vd. inArrayByte là mảng BAI. Nó có là Pointer đâu mà inArrayByte^

Chưa tính tới mảng Variant. Tôi không biết inArrayByte mặt mũi thế nào nhưng Variant là cả một record. Có trường trong đó có thể là string, numeric, object, interface. Vậy thì chưa biết mảng inArrayByte thế nào thì khi copy sang OutArray thì giá trị của trường kia sẽ thế nào? Nó có là interface không, nếu phải thì interface ấy có tồn tại không. Nếu không tồn tại thì tiếp theo truy cập tới interface ấy sẽ có kết quả là "một nhát dao vào lưng".

Mà thôi, không quan trọng chuyện cụ thể như thế nào vì có nhìn được đoạn trước đâu để mà biết 2 mảng kia thế nào. Nhưng chắc chắn là ngoài lỗi inArrayByte^ còn có lỗi khác.

Theo tôi:
- không phải là inArrayByte^ mà là inArrayByte

- hoặc đơn giản là OutArray, hoặc cùng lắm là Pointer(OutArray[0]). Không phải là Pointer(OutArray[0])^

Đấy là nếu tôi còn nhớ đúng. Tôi đã nói rồi, bạn hãy hỏi Tuân vì tôi không cài Delphi.
nhưng Variant là cả một record. Có trường trong đó có thể là string, numeric, object, interface

Em dang bí chỗ này đây, nếu là sizeof là string, number, date thì chạy tốt mà varvariant sau khi move xong là lỗi. Tự vì trong array nó là một mớ hỗn độn.
Chắc để em tìm cách khác.
Cám ơn anh
 
Upvote 0
Em dang bí chỗ này đây, nếu là sizeof là string, number, date thì chạy tốt
Chưa nói tới Variant. Giả sử cả 2 đều là mảng BYTE. Câu lệnh của bạn sẽ thế nào? Theo tôi không thể là inArrayByte^.

Mà chạy tốt nghĩa là gì? Là không có lỗi thực hiện? Nhiều khi không có lỗi nhưng kết quả không như mong đợi do nhập sai tham số. Không phải loại sai vd. cú pháp mà truyền sai tham số. Vd. ông văn thư cần tham số địa chỉ mà bạn truyền cho ông ấy cốc kem thì là sai cú pháp. Nhưng nếu bạn truyền Nguyễn Du 2 thì là chuẩn. Nhưng nếu bạn muốn gửi tới Tràng Tiền 3 mà bạn truyền nhầm là Nguyễn Du 2 thì bạn không thấy lỗi (cú pháp?) nhưng có kết quả sai. Ông văn thư chuyển tài liệu tới Tràng Tiền 3 chứ không phải tới Nguyễn Du 2.

Hãy có 2 mảng BYTE, chưa cần Variant. Sau đó viết code. Không thấy lỗi chưa là gì cả. Hãy kiểm tra các giá trị của OutArray. Nhiều khi không có lỗi nhưng do truyền sai giá trị mà kết quả không như mong đợi.
 
Upvote 0
Chưa nói tới Variant. Giả sử cả 2 đều là mảng BYTE. Câu lệnh của bạn sẽ thế nào? Theo tôi không thể là inArrayByte^.

Mà chạy tốt nghĩa là gì? Là không có lỗi thực hiện? Nhiều khi không có lỗi nhưng kết quả không như mong đợi do nhập sai tham số. Không phải loại sai vd. cú pháp mà truyền sai tham số. Vd. ông văn thư cần tham số địa chỉ mà bạn truyền cho ông ấy cốc kem thì là sai cú pháp. Nhưng nếu bạn truyền Nguyễn Du 2 thì là chuẩn. Nhưng nếu bạn muốn gửi tới Tràng Tiền 3 mà bạn truyền nhầm là Nguyễn Du 2 thì bạn không thấy lỗi (cú pháp?) nhưng có kết quả sai. Ông văn thư chuyển tài liệu tới Tràng Tiền 3 chứ không phải tới Nguyễn Du 2.

Hãy có 2 mảng BYTE, chưa cần Variant. Sau đó viết code. Không thấy lỗi chưa là gì cả. Hãy kiểm tra các giá trị của OutArray. Nhiều khi không có lỗi nhưng do truyền sai giá trị mà kết quả không như mong đợi.
Cái này thì có kiểm tra du liệu rồi anh nếu là si sizeof string la ok còn có lỗi khác không thì chưa thay .
Mục đích của em mò cái này là em muốn tạo 1 mãng mới bắt đầu từ 0 và copy dữ liệu trong mãng cũ (mảng cũ bắt đầu la 1) vào tránh dùng vòng lập mà thôi hihihi
 
Upvote 0
Việc Copy mảng có xác định kích thước của cấu trúc dữ liệu rõ ràng và cố định các phần tử thì dùng Move hay hàm API CopyMemoy là được ngay. Tôi cũng có bài viết về FastArray trên GPE này (không nhớ vở chỗ nào nữa) dùng CopyMemory của array mà các phần tử đều là kiểu Double nên thành công và rất nhanh. Tuy nhiên với mảng mà các phần tử có kiểu String (chưa cần nói đến các kiểu object - IUnknown, IDispatch) thì điều này là khó. Vì string trong SafeArray hay String trong VBA là WideString nó có kích thước tùy vào số ký tự mà nó mang. Nên nếu copy với khối byte bằng SizeOf(Variant)*nCount sẽ lỗi (độ rộng của Variant là 16 hoặc 24 chỉ để lưu các kiểu xác định kích thước như Integer, Long, Double, Byte). Nên bài toán copy SafeArray này tôi đã nói ở trên với bạn Thuyyeu là tạo mảng mới theo cấu trúc bạn muốn và dùng vòng lặp Copy từng phần tử thôi. Chắc bạn ấy còn hy vọng một điều ký diệu khác nữa nên cứ hỏi vậy thôi.
 
Upvote 0
Việc Copy mảng có xác định kích thước của cấu trúc dữ liệu rõ ràng và cố định các phần tử thì dùng Move hay hàm API CopyMemoy là được ngày. Tôi cũng có bài viết về FasstArray trên GPE này (không nhớ vở chỗ nào nữa) dùng CopyMemory của array mà các phần tử đều là kiểu Double nên thành công và rất nhanh. Tuy nhiên với mảng mà các phần tử có String (chưa cần nói đến các kiểu object - IUnknown, IDispatch) thì điều này là khó. Vì string trong SafeArray hay String trong VBA là WideString nó có kích thước tùy vào số ký tự mà nó mang. Nên nếu copy với khối byte bằng SizeOf(Variant) sẽ lỗi (độ rọng của nó là 16 hoặc 24 chỉ để lưu các kiểu xác định kích thước như Integer, Long, Double, Byte). Nên bài toán copy SafeArray này tôi đã nói ở trên với bạn Thuyyeu là tạo mảng mới và dùng vòng lặp Copy từng phần tử thôi. Chắc bạn ấy còn hy vọng một điều gí hơn nên cứ hỏi vậy thôi.
Em làm theo cách anh dùng vòng lặp Copy từng phần tử thì và cũng có 1 cách khác trong Del phi mà em nghĩ cũng dùng vòng lập.
Em chỉ muốn tiềm hiểu thử coi còn cách nào nhanh nữa không đó mà (hình như trong VBA vẫn có cách hay sao ý khác cái FasstArray của anh)
Vấn đề của em hỏi tới đây Begin End; (đã giải quyết chủ yếu em tìm cách tối ưu thôi) :)
Khi nào bí cái khác thì nhờ các anh định hướng giúp em hihihih
Cám ơn các anh quan tâm.
 
Upvote 0
Em làm theo cách anh dùng vòng lặp Copy từng phần tử thì và cũng có 1 cách khác trong Del phi mà em nghĩ cũng dùng vòng lập.
Em chỉ muốn tiềm hiểu thử coi còn cách nào nhanh nữa không đó mà (hình như trong VBA vẫn có cách hay sao ý khác cái FasstArray của anh)
Vấn đề của em hỏi tới đây Begin End; (đã giải quyết chủ yếu em tìm cách tối ưu thôi) :)
Khi nào bí cái khác thì nhờ các anh định hướng giúp em hihihih
Cám ơn các anh quan tâm.

Với mình thì CopyMemory là hết cỡ rồi không biết còn cái gì nữa không. Nếu có bạn share vào đây để mình xem thế nào.
 
Upvote 0
để em lục lại đã em nhớ mang máng là MemCopy thì phải máy cái API này em mù tịt nào là con trỏ ... byte... nhứt đầu (@$%@

MemCopy cung lý cũng là Move hoặc CopyMemory đó. Quan trọng là copy khối dữ liệu có kích cỡ xác định hay không thôi.
 
Upvote 0
Vì tác giả không cho xem chỗ khai báo vd. inArrayByte nên tôi vẫn cho đó là mảng BAI. Và tôi vẫn cho là sai cú pháp. Khi dùng MOVE của Delphi thì không thể là inArrayByte^ được. Và nếu dùng Pointer(OutArray[0])^ thì có lẽ không sai "cú pháp" nhưng chắc chắn sai với mong muốn. Nếu tôi nhớ không nhầm thì tham số thứ nhất của MOVE là const, còn tham số thứ 2 là var. Phải rất cẩn thận để khỏi nhầm khi truyền tham số.

Ở FastArray thì hơi khác chút. Ngoài dùng CopyMemory thì trong đó là copy từ MẢNG VARIANT. Còn ở đây là copy từ MẢNG BYTE. Trong VARIANT có trường mà nó có thể là STRING hoặc OBJECT. Chắc gì những byte của inArrayByte khi copy nào những trường kia có là những pointer tới STRING hoặc OBJECT được "đặt" ở chỗ khác trong memory hay không. Tôi đoán mò inArrayByte là mảng bai do nhìn thấy tên như thế. Nhưng thực chất nó là mảng gì, được tạo như thế nào thì bó tay. Người ta tung 1 dòng code thì bó tay rồi.
 
Upvote 0
Anh @batman1 Em thấy anh viết mấy bài thì có cài Delphi hay ko thì nó cũng ko quan trọng lắm với Anh phải không...
Cơ bản code két và phương pháp anh nhớ hết rồi
nếu em có kẹt cái gì Em hỏi có đầy đủ: mở bài , thân bài và kết thúc ( nói chung càng chi tiết càng tốt ) thì Anh nếu có rảnh chỉ cho Em học với he

Rút kinh nghiệm nhiều lần Em hỏi có vài dòng khiến người trả lời suy đoán Em thấy cũng nhọc :D

Em cảm ơn trước
 
Upvote 0
Anh @batman1 Em thấy anh viết mấy bài thì có cài Delphi hay ko thì nó cũng ko quan trọng lắm với Anh phải không...
Cơ bản code két và phương pháp anh nhớ hết rồi
nếu em có kẹt cái gì Em hỏi có đầy đủ: mở bài , thân bài và kết thúc ( nói chung càng chi tiết càng tốt ) thì Anh nếu có rảnh chỉ cho Em học với he

Rút kinh nghiệm nhiều lần Em hỏi có vài dòng khiến người trả lời suy đoán Em thấy cũng nhọc :D

Em cảm ơn trước
Thôi thôi. Tôi đã viết rồi. Thực ra không phải là tôi đam mê Delphi. Tôi đam mê lập trình Windows API, và để có thể viết code thì tôi dùng Delphi. Bây giờ thôi không muốn mất thời gian nữa. Kỷ nguyên mới thì đam mê mới, nhiều công việc mới. Ở đây có Tuân thì bạn hỏi Tuân thôi.
 
Upvote 0
Pointer(OutArray[0])^: sai ngay đây, dập nát vùng memory có địa chỉ = giá trị chứa trong OutArray[0]
=> Pointer(@OutArray[0])^
 
Upvote 0
Web KT
Back
Top Bottom