Đâ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.
em nghe nói nếu tự học cái đó khó hơn lên trời ấy ... mà tuổi anh em mình ngoài U40 + n rồi ko biết rồi học sao nữa ?!
Em thấy Delphi nó có cái chi đó na ná như VBA và nó viết 1 code duy nhất Make chạy đa nền tảng nên Em mới chịu khó vọc xem sao đó mà
Nhớ ngày đầu Em chuyển qua VB6 cũng rất khó khăn việc khai báo và cú pháp viết sao cho nó hiểu mình vọc diết xong vượt qua cái ngưởng đó vậy là em viết Thư Viện *.dll thấy Tạm ok
Giờ vọc qua Delphi nếu có ai đó có tấm lòng vàng cho 1, 2 code mẫu theo yêu cầu từ đó em mổ sẻ ra từng bước vượt qua cái ngưởng khó khăn ban đầu là tạm ok đó Anh
Nhưng kẹt nổi chưa thấy ai tốt vậy cả Anh ạ .... phải chi anh Biết Em tin 100% anh cho Em ngay lập tức ha
Em được học Pascal, từ hồi trường em còn có cái phòng thực hành toàn máy tính cổ, thỉnh thoảng không hiểu linh kiện máy tính chập cháy kiểu gì bốc khói um cả lên thế là lớp được giải tán . Đi thi thì rụng như sung. Chả là bọn em thi 2 phần viết và thực hành, nghĩ cái cảnh viết mấy tờ giấy thi toàn câu lệnh Pascal mà ớn. Còn thi thực hành thì hên sui (Nếu được máy ngon, thầy dễ tính thì yên tâm chứ gặp máy lởm thì mình chết theo nó luôn), với lại hồi đó sinh viên mà có máy tính riêng là Vip lắm.
Đúng là học Pascal chỉ để rèn luyện tư duy (hay để làm cảnh ...), học nghành kỹ thuật nên ra trường đi làm thì toàn dùng CAD, Word, Excel. Dùng Excel mãi thì có nhu cầu mở rộng tính năng, thông qua lập trình trên ứng dụng nền em được biết đến VBA, VSTO và gần đây là Delphi.
Đối với nhu cầu công việc của em làm trên Excel, khi xét về tốc độ thực thi thì VSTO<VBA<Delphi nên em thấy Delphi sẽ là sự lựa chọn cho những ai ưu tiên về thời gian thực thi mã lệnh.
em nghe nói nếu tự học cái đó khó hơn lên trời ấy ... mà tuổi anh em mình ngoài U40 + n rồi ko biết rồi học sao nữa ?!
Em thấy Delphi nó có cái chi đó na ná như VBA và nó viết 1 code duy nhất Make chạy đa nền tảng nên Em mới chịu khó vọc xem sao đó mà
Nhớ ngày đầu Em chuyển qua VB6 cũng rất khó khăn việc khai báo và cú pháp viết sao cho nó hiểu mình vọc diết xong vượt qua cái ngưởng đó vậy là em viết Thư Viện *.dll thấy Tạm ok
Giờ vọc qua Delphi nếu có ai đó có tấm lòng vàng cho 1, 2 code mẫu theo yêu cầu từ đó em mổ sẻ ra từng bước vượt qua cái ngưởng khó khăn ban đầu là tạm ok đó Anh
Nhưng kẹt nổi chưa thấy ai tốt vậy cả Anh ạ .... phải chi anh Biết Em tin 100% anh cho Em ngay lập tức ha
Không biết bài đầu có đc gọi là lòng tốt không? . Phải mất nhiều thời gian mình mới có thể hiểu chắc chắn cơ về tạo DLL theo cách gọi API đó đấy. Ở Việt Nam này chưa có ai làm video hay viết tài liệu hướng dẫn món đó cả (hoặc mình chưa thể tìm ra). Mấy món Java, Python, Rube, .NET không (dùng framework) không thể tạo được loại thư viện biên dịch ra mã máy đó đâu nhé. Dân lập trình hệ thống, thư viện lõi trong các chương trình lớn phải dùng C, C++, Delphi mới làm món đó để tối ưu chương trình. Ví dụ một cái hàm LEFT hay các hàm xử lý chuỗi thôi, Delphi nó dùng mã nguồn là Assempler để tối ưu. Giờ đây tôi đã vén màn ra cho mọi người thấy để lựa chọn... Chỉ cần nhìn thấy "ánh sáng cuối đường hầm" là biết lối đi. Delphi hay .NET không phải món dễ mò như VB6, VBA đâu. Nên bạn cứ cẩn thận đọc tài liệu từng bước. Bạn đang mới học nhưng muốn lấy ngay một ví dụ (có mã nguồn) mà nó cao hẳn hoặc phức tạp (so với người mới biết) để người khác giúp từ đó học là sai phương pháp. Người khác lên đây cũng đòi một ví dụ muốn chia sẻ dữ liệu dùng Socket với giao thức TCP/IP nữa thì loạn ngay. Tôi code cho bạn ví dụ như bạn muốn dưới đây nhưng cũng chỉ để biết ở mức đó hoặc ngẫm ra "ah, nó làm đc thế" chứ không học được gì căn cơ từ đó nếu không có học từ đầu, từng bước. Nếu các bạn muốn chứng minh Delphi làm được gì hay dễ không thì ví dụ đó lại quá nhỏ bé.
(*) Đây là code viết hàm chạy SQL để lấy dữ liệu từ file Excel và đỏ ra một ô trên Excel. Bạn chạy nó trong Delphi hoặc chạy trong VBA thì theo cách khai báo API video bài 1 tôi đã hướng dẫn. Tham số khai báo OleVariant trong Delphi là Variant ở VBA/VB6, Longint chính là Long ở VBA/VB6. Bạn có thể chạy thử nếu khai báo VBA có lỗi thì đưa lên tôi có thể chỉnh cho.
function RunSQLToRange(sFullName, sSQL: OleVariant; Range: OleVariant): Longint; stdcall;
var
cnn: TADOConnection;
qry: TADOQuery;
begin
cnn := TADOConnection.Create(nil);
try
cnn.ConnectionString := 'Provider=Microsoft.ACE.OLEDB.12.0;Data Source=' + sFullName +
'Extended Properties="Excel 12.0 Xml;HDR=YES";';
cnn.Connected := True;
qry := TADOQuery.Create(nil);
try
qry.Connection := cnn;
qry.SQL.Text := sSQL;
qry.Open;
Result := Range.CopyFromRecordset(qry.Recordset); //copy data from recordset to Excel range
finally
qry.Free;
end;
finally
cnn.Free;
end;
end;
Tôi muốn nhắn thêm với bạn một ý nữa là việc bạn chọn cách học kiểu mò mẫm là sai (trong khi có cơ hội để học bản bản từ ebook, vẫn free nhé) và bên cạch đó bạn không nhận ra được giá trị giúp đỡ đúng mức và dùng từ "lòng tốt" là phật lòng người khác mặc dù họ cũng không cần phải được công nhận điều đó.
Trước mình học ở trường đại học được học 2 kỳ visual basic 6.0, lập trình được mấy chương trình nhỏ chuyên ngành, ra trường đi làm thì chẳng ai dùng VB 6.0 cả, chỗ làm thì lại dùng Free pascal sử dụng Lazarus để soạn code và biên dịch, chuyển từ VB 6.0 sang thấy khác hoàn toàn, nhiều cái mới, học thì toàn học vẹt để làm được cái chương trình nhỏ để dùng. Nhưng cái ngôn ngữ này ít người dùng và ít tài liệu tham khảo, nên người hướng dẫn mình code nghỉ làm thì mình cũng nghỉ chơi luôn, Hiện mình đang chuyển sang C# vì thấy nó rất phổ biến, hỗ trợ nhiều, không biết gì thì lên mạng hỏi cái ra ngay.
Mình thấy cái delphi của anh Tuân sử dụng object pascal giống cái trước mình học, nhưng mình thấy dùng C# vẫn khoái hơn, với lại học cái C# nó gần với mấy cái java hơn, nên khi chuyển sang java cũng dễ.
Em thấy cái này cũng định nghiên cứu chơi nhưng tìm giáo trình tiếng việt (em bị dốt tiếng anh) về nó khó quá (Chỉ thấy giáo tình của ĐHCT mà bản 6, trong khi bây giờ đã là 10 rồi). Vậy anh em nào có giáo trình tiếng việt chỉ em tham khảo với.
Trước mình học ở trường đại học được học 2 kỳ visual basic 6.0, lập trình được mấy chương trình nhỏ chuyên ngành, ra trường đi làm thì chẳng ai dùng VB 6.0 cả, chỗ làm thì lại dùng Free pascal sử dụng Lazarus để soạn code và biên dịch, chuyển từ VB 6.0 sang thấy khác hoàn toàn, nhiều cái mới, học thì toàn học vẹt để làm được cái chương trình nhỏ để dùng. Nhưng cái ngôn ngữ này ít người dùng và ít tài liệu tham khảo, nên người hướng dẫn mình code nghỉ làm thì mình cũng nghỉ chơi luôn, Hiện mình đang chuyển sang C# vì thấy nó rất phổ biến, hỗ trợ nhiều, không biết gì thì lên mạng hỏi cái ra ngay.
Mình thấy cái delphi của anh Tuân sử dụng object pascal giống cái trước mình học, nhưng mình thấy dùng C# vẫn khoái hơn, với lại học cái C# nó gần với mấy cái java hơn, nên khi chuyển sang java cũng dễ.
Đúng là Delphi ở Việt Nam dùng ít. Ở Nhật, Pháp, Đức, Nga, Pháp, Mỹ thì nhiều. Search tài liệu Delphi tiếng Anh thì nhiều vô số, tiếng Việt thì hạn chế.
Em thấy cái này cũng định nghiên cứu chơi nhưng tìm giáo trình tiếng việt (em bị dốt tiếng anh) về nó khó quá (Chỉ thấy giáo tình của ĐHCT mà bản 6, trong khi bây giờ đã là 10 rồi). Vậy anh em nào có giáo trình tiếng việt chỉ em tham khảo với.
Theo quan điểm cá nhân em thì, Khó khăn với những người không chuyên về tin học hiện nay muốn học Delphi, là chưa tìm được cuốn Ebook giáo trình bằng tiếng Việt nào chất lượng và bài bản.
Để người học bước đầu làm quen và học một cách có hệ thống những kiến thức căn bản rồi từ đó phát triển theo hướng riêng phục vụ công việc của mình.
Còn Ebook bằng tiếng Anh, thì em nói thật là một số thuật ngữ phải là dân chuyên mới hiểu còn không thì khó lắm, vậy phương án học bằng Ebook tiếng anh ngoài sự lỗ lực của bản thân còn cần sự hỗ trợ của chuyên gia về Delphi trên diễn đàn nữa.
Em rất cảm ơn Bác Nguyễn Duy Tuân đã chỉ dẫn và sửa code cho em. Em rất mong bác Tuân và các chuyên gia của diễn đàn tiếp tục đăng bài chia sẻ nhiều hơn Về Delphi để mọi thành viên có cơ hội tiếp cận nó dễ dàng hơn.
Đúng là Delphi ở Việt Nam dùng ít. Ở Nhật, Pháp, Đức, Nga, Pháp, Mỹ thì nhiều. Search tài liệu Delphi tiếng Anh thì nhiều vô số, tiếng Việt thì hạn chế.
Bài đã được tự động gộp:
Theo mình thì bạn cứ dùng giáo trình của ĐHCT đi, với người mới bắt đầu khá dễ tiếp cận. Bạn có căn bản rồi thì đọc code trên mạng sẽ nhanh lắm.
Thực ra mình khá bận với công việc hiện tại. Việc làm tư liệu Delphi mất khá nhiều thời gian để dùng câu từ giải thích dễ hiểu, cũng cố thu xếp lắm mình với tạo được cái video hướng dẫn kỹ bài 1 về học Delphi căn bản. Bài học này giúp các bạn biết tạo lập môi trường ban đầu để biên dịch ra chương trình đầu tiên cho mình 'Hello Delphi!". Loạt video về hoạc Delphi tôi muốn xây dựng free để đáp ứng bước học cơ bản nhất để từ đó người Việt biết đến và ứng dụng cho đúng cía mình muốn. Và khuyến khích các bạn cần đọc lại ngôn ngữ Object Pascal.
Với những bạn đã lập trình VBA thì lưu ý là: ngôn ngữ chúng ta lập trình chính là VB - Visual Basic. Việc ta lập trình trong VBA chỉ là dùng ngôn ngữ để can thiệp vào các Object của ứng dụng như Workbook, Worksheet, Range...
Với Delphi cũng thế. Ngôn ngữ là Object Pascal, dùng trong Delphi để điều khiển và tạo ra các Object mà thôi. Vậy nên cần học ngô ngữ Pascal mới làm được Delphi.
Code sửa theo Delphi như sau:
Khi viết hàm hay procedure cho Delphi để xử lý Excel, bạn luôn truyền tham số Object mẹ cho nó để trong code xử lý nó hoặc thằng con. Không bao giờ trong hàm hay thủ tục con lại đi nhận Excel.Application -> Code này chỉ dành cho thủ tục đầu tiên hoặc hàm trong DLL gửi nó từ VBA vào.
Mã:
Uses
ComObj;
Function CheckIfSheetExists(Workbook: OleVariant; shName: String): Boolean;
var
I: Integer;
begin
Result:= False;
For I := 1 to Workbook.Sheets.Count do
begin
If Workbook.Sheets[I].Name = shName Then
begin
Result:= True;
Break; // hoặc dùng Exit (Break là chỉ thoát khỏi vòng lặp; Exit là thoát khỏi hàm luôn;
end;
end;
end;
Cảm ơn bác đã sửa code giúp em!
Ở đây là bác dùng vòng lặp For .. To . Em có một chút tò mò là Vòng lặp For .. In không hỗ trợ trong Delphi 7 các phiên bản sau mới hỗ trợ. Vậy như trong đoạn Code em nêu trên nếu sửa theo vòng lặp For .. In thì Khai báo biến và viết code thế nào ạ?
Không biết bài đầu có đc gọi là lòng tốt không? . Phải mất nhiều thời gian mình mới có thể hiểu chắc chắn cơ về tạo DLL theo cách gọi API đó đấy. Ở Việt Nam này chưa có ai làm video hay viết tài liệu hướng dẫn món đó cả (hoặc mình chưa thể tìm ra). Mấy món Java, Python, Rube, .NET không (dùng framework) không thể tạo được loại thư viện biên dịch ra mã máy đó đâu nhé. Dân lập trình hệ thống, thư viện lõi trong các chương trình lớn phải dùng C, C++, Delphi mới làm món đó để tối ưu chương trình. Ví dụ một cái hàm LEFT hay các hàm xử lý chuỗi thôi, Delphi nó dùng mã nguồn là Assempler để tối ưu. Giờ đây tôi đã vén màn ra cho mọi người thấy để lựa chọn... Chỉ cần nhìn thấy "ánh sáng cuối đường hầm" là biết lối đi. Delphi hay .NET không phải món dễ mò như VB6, VBA đâu. Nên bạn cứ cẩn thận đọc tài liệu từng bước. Bạn đang mới học nhưng muốn lấy ngay một ví dụ (có mã nguồn) mà nó cao hẳn hoặc phức tạp (so với người mới biết) để người khác giúp từ đó học là sai phương pháp. Người khác lên đây cũng đòi một ví dụ muốn chia sẻ dữ liệu dùng Socket với giao thức TCP/IP nữa thì loạn ngay. Tôi code cho bạn ví dụ như bạn muốn dưới đây nhưng cũng chỉ để biết ở mức đó hoặc ngẫm ra "ah, nó làm đc thế" chứ không học được gì căn cơ từ đó nếu không có học từ đầu, từng bước. Nếu các bạn muốn chứng minh Delphi làm được gì hay dễ không thì ví dụ đó lại quá nhỏ bé.
(*) Đây là code viết hàm chạy SQL để lấy dữ liệu từ file Excel và đỏ ra một ô trên Excel. Bạn chạy nó trong Delphi hoặc chạy trong VBA thì theo cách khai báo API video bài 1 tôi đã hướng dẫn. Tham số khai báo OleVariant trong Delphi là Variant ở VBA/VB6, Longint chính là Long ở VBA/VB6. Bạn có thể chạy thử nếu khai báo VBA có lỗi thì đưa lên tôi có thể chỉnh cho.
function RunSQLToRange(sFullName, sSQL: OleVariant; Range: OleVariant): Longint; stdcall;
var
cnn: TADOConnection;
qry: TADOQuery;
begin
cnn := TADOConnection.Create(nil);
try
cnn.ConnectionString := 'Provider=Microsoft.ACE.OLEDB.12.0;Data Source=' + sFullName +
'Extended Properties="Excel 12.0 Xml;HDR=YES";';
cnn.Connected := True;
qry := TADOQuery.Create(nil);
try
qry.Connection := cnn;
qry.SQL.Text := sSQL;
qry.Open;
Result := Range.CopyFromRecordset(qry.Recordset); //copy data from recordset to Excel range
finally
qry.Free;
end;
finally
cnn.Free;
end;
end;
Tôi muốn nhắn thêm với bạn một ý nữa là việc bạn chọn cách học kiểu mò mẫm là sai (trong khi có cơ hội để học bản bản từ ebook, vẫn free nhé) và bên cạch đó bạn không nhận ra được giá trị giúp đỡ đúng mức và dùng từ "lòng tốt" là phật lòng người khác mặc dù họ cũng không cần phải được công nhận điều đó.
Em thấy cái này cũng định nghiên cứu chơi nhưng tìm giáo trình tiếng việt (em bị dốt tiếng anh) về nó khó quá (Chỉ thấy giáo tình của ĐHCT mà bản 6, trong khi bây giờ đã là 10 rồi). Vậy anh em nào có giáo trình tiếng việt chỉ em tham khảo với.
MÌnh mới thử lại nó vẫn vậy ... hay thủ tục gọi Hàm từ Excel mình viết sai ... có thay tham số từ String sang Variant từ Excel nó vẫn vậy
Nhờ bạn xem dùm ... Xin cảm ơn
Mã:
Declare Function RunSQLToRange Lib "VBLibrary.dll" (ByVal ExcelPath As String, ByVal sSQL As String, ByVal Target As Range)
Sub Main()
Dim FilePath As String, DataRange As String
''DataRange = "Data_Nhap$A2:J2000"
DataRange = "Data_Nhap$"
''DataRange = "SELECT * FROM [Data_Nhap$A2:J2000]"
''DataRange = "SELECT * FROM [Data_Nhap$]"
FilePath = ThisWorkbook.Path & "\Data.xlsb"
Call RunSQLToRange(FilePath, DataRange, Range("A2"))
End Sub
MÌnh mới thử lại nó vẫn vậy ... hay thủ tục gọi Hàm từ Excel mình viết sai ... có thay tham số từ String sang Variant từ Excel nó vẫn vậy
Nhờ bạn xem dùm ... Xin cảm ơn
Mã:
Declare Function RunSQLToRange Lib "VBLibrary.dll" (ByVal ExcelPath As String, ByVal sSQL As String, ByVal Target As Range)
Sub Main()
Dim FilePath As String, DataRange As String
''DataRange = "Data_Nhap$A2:J2000"
DataRange = "Data_Nhap$"
''DataRange = "SELECT * FROM [Data_Nhap$A2:J2000]"
''DataRange = "SELECT * FROM [Data_Nhap$]"
FilePath = ThisWorkbook.Path & "\Data.xlsb"
Call RunSQLToRange(FilePath, DataRange, Range("A2"))
End Sub
Bạn khai báo API bên VBA sai. Như tôi đã bôi đậm bài trước, kiểu OleVariant -> Variant. Trong hàm viết ở Delphi tôi dùng OleVariant mà. Bạn khai báo sang String là sai.
Khai báo đúng như sau
Declare Function RunSQLToRange Lib "VBLibrary.dll" (ByVal ExcelPath As Variant, ByVal sSQL As Variant, ByVal Target As Variant)
Bạn khai báo API bên VBA sai. Như tôi đã bôi đậm bài trước, kiểu OleVariant -> Variant. Trong hàm viết ở Delphi tôi dùng OleVariant mà. Bạn khai báo sang String là sai.
Khai báo đúng như sau
Declare Function RunSQLToRange Lib "VBLibrary.dll" (ByVal ExcelPath As Variant, ByVal sSQL As Variant, ByVal Target As Variant)
MÌnh mới thử lại nó vẫn thế mà code trong Delphi như sau
Mã:
library VBLibrary;
{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Data.DB, Data.Win.ADODB;
{$R *.res}
//////// Khu Vuc Viet Code
function RunSQLToRange(sFullName, sSQL: OleVariant; Range: OleVariant): Longint; stdcall;
var
cnn: TADOConnection;
qry: TADOQuery;
begin
cnn := TADOConnection.Create(nil);
try
{cnn.ConnectionString := 'Provider=Microsoft.ACE.OLEDB.12.0;Data Source=' + sFullName +
'Extended Properties="Excel 12.0 Xml;HDR=YES";'; }
cnn.ConnectionString := 'Provider=Microsoft.ACE.OLEDB.12.0;Data Source=' + sFullName +
';Extended Properties="Excel 12.0 Xml;HDR=YES";';
cnn.Connected := True;
qry := TADOQuery.Create(nil);
try
qry.Connection := cnn;
qry.SQL.Text := sSQL;
qry.Open;
Result := Range.CopyFromRecordset(qry.Recordset); //copy data from recordset to Excel range
finally
qry.Free;
end;
finally
cnn.Free;
end;
end;
///
exports
RunSQLToRange;
begin
end.
MÌnh mới thử lại nó vẫn thế mà code trong Delphi như sau
Mã:
library VBLibrary;
{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Data.DB, Data.Win.ADODB;
{$R *.res}
//////// Khu Vuc Viet Code
function RunSQLToRange(sFullName, sSQL: OleVariant; Range: OleVariant): Longint; stdcall;
var
cnn: TADOConnection;
qry: TADOQuery;
begin
cnn := TADOConnection.Create(nil);
try
{cnn.ConnectionString := 'Provider=Microsoft.ACE.OLEDB.12.0;Data Source=' + sFullName +
'Extended Properties="Excel 12.0 Xml;HDR=YES";'; }
cnn.ConnectionString := 'Provider=Microsoft.ACE.OLEDB.12.0;Data Source=' + sFullName +
';Extended Properties="Excel 12.0 Xml;HDR=YES";';
cnn.Connected := True;
qry := TADOQuery.Create(nil);
try
qry.Connection := cnn;
qry.SQL.Text := sSQL;
qry.Open;
Result := Range.CopyFromRecordset(qry.Recordset); //copy data from recordset to Excel range
finally
qry.Free;
end;
finally
cnn.Free;
end;
end;
///
exports
RunSQLToRange;
begin
end.
Cuối cùng Mình phải sửa code lại vầy nó Chạy rất nhanh ... thử 65536 dòng nó bay cái vèo
Code cũ
Mã:
qry.SQL.Text := sSQL;
Code mới thay thế
Mã:
qry.SQL.Text := 'SELECT * FROM' + sSQL;
Với Mình ADO chỉ quan tâm 4 cái sau:
1/ Tạo kết nối với các CSDL
2/ Lấy dữ Liệu lên
3/ Ghi dữ liệu xuông
4/ lấy dữ liệu cho vào Mãng ... xong từ đó Cộng, trừ, nhân chia trong mãng .... Còn thuần ADO là thua mà ko dại gì lao vô đó mệt lăm
....
Cảm Ơn Bạn đã chỉ dẫn