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,652
Được thích
10,140
Giới tính
Nam
Nghề nghiệp
Giáo viên, CEO tại Bluesofts
Lần chỉnh sửa cuối:
OK ... quả thực ko có bạn chỉ mò chưa biết khi nàoView attachment 204906

Ok bạn. Thực ra vấn đề bạn đang trao đổi trên topic này là ngoài mong đợi của mình. Mình muốn mọi người trao đổi cái căn bản thôi, vì nhiều người ngôn ngữ chưa biết. Các câu hỏi của bạn thực tế khá sâu trong hệ thống, ngay cả người làm Delphi lâu chưa chắc biết những vấn đề đang trao đổi trên đây đâu.
 
Upvote 0
Chạy tốt chứ Bạn
Ko hiểu sao Mạnh mới sửa TDateTime sang string chạy code nó đơ luôn
Cái này nó đơ là nó bị lỗi không đúng kiểu dữ liệu sArr[i,9] la Date
procedure FilterDate1dArray( sArr: OleVariant; const Fdate: TDateTime; const Edate: TDateTime;
const ColDate: Longint; Range: OleVariant) ; stdcall;

Declare Sub FilterDate1dArray Lib "D:\Soft\Delphi\vi duDelphi\DLL giaiphapexcel\Win32\Debug\DllATuan.dll" _
(ByVal sArr As Variant, _
ByVal Fdate As Date, ByVal Edate As Date, _
ByVal ColDate As Long, ByVal Target As Variant)
 
Upvote 0
Cái này nó đơ là nó bị lỗi không đúng kiểu dữ liệu sArr[i,9] la Date
procedure FilterDate1dArray( sArr: OleVariant; const Fdate: TDateTime; const Edate: TDateTime;
const ColDate: Longint; Range: OleVariant) ; stdcall;

Declare Sub FilterDate1dArray Lib "D:\Soft\Delphi\vi duDelphi\DLL giaiphapexcel\Win32\Debug\DllATuan.dll" _
(ByVal sArr As Variant, _
ByVal Fdate As Date, ByVal Edate As Date, _
ByVal ColDate As Long, ByVal Target As Variant)
nếu máy mạnh mà sửa const Fdate là đơ liền ...thì mới nói cái cột Date kia phải chuẩn
và kiểu dữ liều là số trong cột khác không chuẩn nó cũng đơ
eeeeeeeeeeee.PNG
 
Lần chỉnh sửa cuối:
Upvote 0
OK ... quả thực ko có bạn chỉ mò chưa biết khi nàoView attachment 204906
Không nhất thiết, tức thế cũng được mà không thế cũng được, là phải bỏ Const.

Nếu trong DLL có

function UniMsgbox(const Message1: String; const TimeOut: integer=64; const Format: integer=3): OleVariant;

Và
1. Trong VBA có
Declare Function UniMsgbox Lib "VBLibrary.dll" (ByVal message1 As String, Optional ByVal TimeOut As Long = 3, Optional ByVal Format As Long = 64) As Variant

thì bắt buộc phải gọi: x = UniMsgbox(StrConv(KM, vbUnicode), 30, 68)

2. Trong VBA có
Declare Function UniMsgbox Lib "VBLibrary.dll" (ByVal message1 As Long, Optional ByVal TimeOut As Long = 3, Optional ByVal Format As Long = 64) As Variant

thì bắt buộc phải gọi: x = UniMsgbox(StrPtr(KM), 30, 68)
 
Upvote 0
nếu máy mạnh mà sửa const Fdate là đơ liền ...thì mới nói cái cột Date kia phải chuẩn
và kiểu dữ liều là số trong cột khác không chuẩn nó cũng đơ
View attachment 204920

Mình thấy máy mình chạy ok không lỗi gì hết bó tay, ban kiem tra ky lai

Mã:
    Dim Arr As Variant
    Dim Fdate As String, Edate As String
    Fdate = [I1].Value ''Ngay bat dau
    Edate = [I2].Value ''ngay ket thuc
 
    Arr = Sheet1.Range("A2:I65536") '.Value
 
    Application.ScreenUpdating = False
    Application.EnableEvents = False
'    MsgBox "Thuy"
        'If Not Intersect(Target, [I1:I2]) Is Nothing Then
            'If Not IsNumeric(Target) And Not IsDate(Target) Then
            '    Target = ""
            '    Target.Select
            'Else
                Range("K3:S1000").ClearContents
                FilterDate1dArray Arr, Fdate, Edate, 9, [K3]  ''Tham s? 9 là c?t ngay/thang/nam
                '/FilterDate1dArray Sheet1.Range("A2:I65536").Value, Sheet1.Range("I1").Value, Sheet1.Range("I2").Value, 9, Sheet1.Range("K3")
                ''Tham s? 9 là c?t ngay/thang/nam
            '    Target.Select
            'End If
        'End If
    Application.EnableEvents = True
    Application.ScreenUpdating = True

manh ok.jpg
 
Upvote 0
ta thêm dòng sau nữa là an toàn còn dữ liệu cà chớn thì nghỉ chơi
Mã:
except
    ShowMessage('Kiểu dữ liệu không chuẩn kiểm tra lại');
end;
Bài đã được tự động gộp:

Mình thấy máy mình chạy ok không lỗi gì hết bó tay, ban kiem tra ky lai

Mã:
    Dim Arr As Variant
    Dim Fdate As String, Edate As String
    Fdate = [I1].Value ''Ngay bat dau
    Edate = [I2].Value ''ngay ket thuc

    Arr = Sheet1.Range("A2:I65536") '.Value

    Application.ScreenUpdating = False
    Application.EnableEvents = False
'    MsgBox "Thuy"
        'If Not Intersect(Target, [I1:I2]) Is Nothing Then
            'If Not IsNumeric(Target) And Not IsDate(Target) Then
            '    Target = ""
            '    Target.Select
            'Else
                Range("K3:S1000").ClearContents
                FilterDate1dArray Arr, Fdate, Edate, 9, [K3]  ''Tham s? 9 là c?t ngay/thang/nam
                '/FilterDate1dArray Sheet1.Range("A2:I65536").Value, Sheet1.Range("I1").Value, Sheet1.Range("I2").Value, 9, Sheet1.Range("K3")
                ''Tham s? 9 là c?t ngay/thang/nam
            '    Target.Select
            'End If
        'End If
    Application.EnableEvents = True
    Application.ScreenUpdating = True

View attachment 204921
OK mới coi lại chạy tốt rồi mạnh bẩy lỗi đó nữa là hết đơ ... kiểu dữ liệu cà chớn là nghỉ chơi
 
Lần chỉnh sửa cuối:
Upvote 0
ta thêm dòng sau nữa là an toàn còn dữ liệu cà chớn thì nghỉ chơi
Mã:
except
    ShowMessage('Kiểu dữ liệu không chuẩn kiểm tra lại');
end;
Bài đã được tự động gộp:


OK mới coi lại chạy tốt rồi mạnh bảy lỗi đó nữa là hết đơ ... kiểu dữ liệu cà chớn là nghỉ chơi
Ban kiểm tra Type của OleVariant được mà
if String then....
if Date then ....
if number then....
 
Upvote 0
Còn nếu muốn chơi tới bến và
Trong VBA
Declare Function UniMsgbox Lib "VBLibrary.dll" (message1 As Long, Optional ByVal TimeOut As Long = 3, Optional ByVal Format As Long = 64) As Variant

thì bắt buộc phải gọi: x = UniMsgbox(ByVal StrPtr(KM), 30, 68)
 
Upvote 0
Ban kiểm tra Type của OleVariant được mà
if String then....
if Date then ....
if number then....
Viết cho Mạnh chi tiết cái đi mới nhập môm mà cứ gọi ý vậy nhiều khi viết sai à
Bài đã được tự động gộp:

Còn nếu muốn chơi tới bến và
Trong VBA
Declare Function UniMsgbox Lib "VBLibrary.dll" (message1 As Long, Optional ByVal TimeOut As Long = 3, Optional ByVal Format As Long = 64) As Variant

thì bắt buộc phải gọi: x = UniMsgbox(ByVal StrPtr(KM), 30, 68)
em thấy Anh rành Delphi mà ... mấy năm trước thấy bài anh viết ... Mai mốt Em khó khăn gì Mong Anh chỉ cho Em học với
 
Upvote 0
Mạnh đang viết 1 hàm mới trên Delphi mà mắc kẹt 1 vài vấn đề úp bài nhờ các Bạn chỉ dùm
1/ code trên VBA
Mã:
If InStr(1, UCase(Arr(1, i)), UCase(Target.Value), 1) Then
Vậy cái Hàm InStr này trên Delphi mình xài hàm nào tương đương nó hay có cách nào khác xử lý vấn đề đó

2/ Trường hợp 2 code trên VBA
Mã:
If Range("E83").Value = Empty Then MsgBox "OK"
Vậy cái Empty này trên Delphi có mấy cách Xài ?!
Xin cảm ơn
 
Upvote 0
Mạnh đang viết 1 hàm mới trên Delphi mà mắc kẹt 1 vài vấn đề úp bài nhờ các Bạn chỉ dùm
1/ code trên VBA
Mã:
If InStr(1, UCase(Arr(1, i)), UCase(Target.Value), 1) Then
Vậy cái Hàm InStr này trên Delphi mình xài hàm nào tương đương nó hay có cách nào khác xử lý vấn đề đó

2/ Trường hợp 2 code trên VBA
Mã:
If Range("E83").Value = Empty Then MsgBox "OK"
Vậy cái Empty này trên Delphi có mấy cách Xài ?!
Xin cảm ơn
1/ Có nhiều cách nhưng theo mình mình vận dụng 3 hàm này
pos
copy
Length
AnsiUpperCase
2/ hình như là Nil thì phải
 
Upvote 0
1/ Có nhiều cách nhưng theo mình mình vận dụng 3 hàm này
pos
copy
Length
AnsiUpperCase
2/ hình như là Nil thì phải
Cảm ơn bạn mai mạnh thử xem sao có chi bạn chỉ dùm Cảm Ơn .... nay code khá hơn một chút
chỉ rất khó khăn cách xài hàm trong Delphi và khai báo sử dụng nó ... bước qua cái ải này là Mạnh viết code tạm ok :p:D
Bài đã được tự động gộp:

Mạnh mới viết xong 1 Hàm lọc duy nhất sử dụng Dic .... Úp nhờ cách Bạn xem dùm cách Viết vậy là ok chưa cần điều chỉnh gì thêm vvv
1/ Code trong Delphi
Mã:
function GetDicKeys(sArr: OleVariant; const ColDic : longint):OleVariant;stdcall;
var
   Tmp,Dic,Arr    : OleVariant;
   i, j,k    : Longint;
   lcols,lRows    : Longint;
begin
   try
   Dic := CreateOleObject('Scripting.Dictionary') ;
   k := 0;
   lRows := VarArrayHighBound(sArr, 1);  //So dong ko xac dinh
   lCols := VarArrayHighBound(sArr, 2);  //So Cot  ko Xac dinh
   Arr := VarArrayCreate([1, lRows , 1, lcols],varVariant);        {Ap dung Cho Mang 1dArray}
   for i := 1 to lRows do begin
     if string(sArr[i, ColDic]) <>'' then begin
       Tmp := trim(sArr[i, ColDic]);
       if  not dic.Exists(Tmp) then begin
       k := k + 1;
       Dic.Add(Tmp, k);
         For j := 1 To lcols do begin
           Arr[k, j] := sArr[i, j];
         End;
       end;
     end;
   end;
   Result := Arr;
   except
     dic := Unassigned;
     //ShowMessage('Kiểu dữ liệu không chuẩn kiểm tra lại');
   end;
end;
2/ Khai báo sử dụng trên VBA
Mã:
Declare Function GetDicKeys Lib "VBLibrary.dll" (ByVal Arr As Variant, ByVal ColDic As Long) As Variant

Sub Test_GetDicKeys()
    Dim Arr As Variant
    Arr = [A4:E100].Value
    ''Arr = Sheet2.Range("A4", Sheet2.[A65536].End(3).Resize(, 5)).Value
    Range("L4:P1000").ClearContents
    Arr = GetDicKeys(Arr, 2) ''Tham so 2 la Cot loc duy nhat
    Range("L4").Resize(UBound(Arr, 1), UBound(Arr, 2)) = Arr
End Sub
Code chạy bay vèo vèo ... :D:p:D:rolleyes:
xin cảm ơn
 
Lần chỉnh sửa cuối:
Upvote 0
Mạnh đang viết 1 hàm mới trên Delphi mà mắc kẹt 1 vài vấn đề úp bài nhờ các Bạn chỉ dùm
1/ code trên VBA
Mã:
If InStr(1, UCase(Arr(1, i)), UCase(Target.Value), 1) Then
Vậy cái Hàm InStr này trên Delphi mình xài hàm nào tương đương nó hay có cách nào khác xử lý vấn đề đó
Sao bạn không đọc help? Nhiều người không biết là ở bất cứ nơi đâu (Excel, VB, VBA, Delphi) cũng có help. Tủ sách to đùng ngay bên cạnh mà lại đi tìm ở đâu đó, hỏi ai đó?

Tôi chụp cho bạn help trong Delphi. Nhiều mục lắm.
-----------
Không biết các phiên bản mới thế nào chứ Delphi 5 không có hàm nào giống Instr 100%. Mà chắc cũng chả có đâu. Nhưng gần giống thì có, vd. Pos, StrPos.

Ví dụ Instr cho phép tìm vd. từ ký tự thứ 5 trở đi. Nhưng cũng có thể biến tấu.
Mã:
procedure TForm1.Button1Click(Sender: TObject);
var
  p, p1: PChar;
  s: string;
  k: integer;
begin
  s := 'he hic hic hu hu blala hi hic hic ho ho';
  // tim 'hic hic' bat dau tu 1
  p := strpos(PChar(s), 'hic hic');
  // se thay 'hic hic hu hu blala hi hic hic ho ho'
  showmessage(p);
  p1 := Pointer(s); // lub PChar(s)
  inc(p1, 4);
  // tim 'hic hic' bat dau tu ky tu thu 5
  p := StrPos(p1, 'hic hic');
  // se thay 'hic hic ho ho'
  showmessage(p);
  // tim vi tri 'hic hic' bat dau tu 1
  k := pos('hic hic', s);
  showmessage(IntToStr(k));
end;
help1.JPG
help2.JPG
help3.JPG
help4.JPG
help5.JPG
help6.JPG
help7.JPG
 
Upvote 0
Sao bạn không đọc help? Nhiều người không biết là ở bất cứ nơi đâu (Excel, VB, VBA, Delphi) cũng có help. Tủ sách to đùng ngay bên cạnh mà lại đi tìm ở đâu đó, hỏi ai đó?

Tôi chụp cho bạn help trong Delphi. Nhiều mục lắm.
-----------
Không biết các phiên bản mới thế nào chứ Delphi 5 không có hàm nào giống Instr 100%. Mà chắc cũng chả có đâu. Nhưng gần giống thì có, vd. Pos, StrPos.

Ví dụ Instr cho phép tìm vd. từ ký tự thứ 5 trở đi. Nhưng cũng có thể biến tấu.
Mã:
procedure TForm1.Button1Click(Sender: TObject);
var
  p, p1: PChar;
  s: string;
  k: integer;
begin
  s := 'he hic hic hu hu blala hi hic hic ho ho';
  // tim 'hic hic' bat dau tu 1
  p := strpos(PChar(s), 'hic hic');
  // se thay 'hic hic hu hu blala hi hic hic ho ho'
  showmessage(p);
  p1 := Pointer(s); // lub PChar(s)
  inc(p1, 4);
  // tim 'hic hic' bat dau tu ky tu thu 5
  p := StrPos(p1, 'hic hic');
  // se thay 'hic hic ho ho'
  showmessage(p);
  // tim vi tri 'hic hic' bat dau tu 1
  k := pos('hic hic', s);
  showmessage(IntToStr(k));
end;
View attachment 205115
View attachment 205116
View attachment 205117
View attachment 205118
View attachment 205119
View attachment 205120
View attachment 205121
phải nói thật là em cũng chưa biết xài help trong Delphi sao nữa ... bấm cái gì nó ra help ... Em xài bản XE6
tiện đây Anh chỉ Em luôn với
Cảm ơn Anh
Capture.PNG
Em mới thử F1 nó báo lỗi
hhhhhhhhhhhhhh.PNG
Anh úp cho Em xin cái File help trên máy Anh với
 
Lần chỉnh sửa cuối:
Upvote 0
phải nói thật là em cũng chưa biết xài help trong Delphi sao nữa ... bấm cái gì nó ra help ... Em xài bản XE6
tiện đây Anh chỉ Em luôn với
Cảm ơn Anh
View attachment 205123
Em mới thử F1 nó báo lỗi
View attachment 205125
Anh úp cho Em xin cái File help trên máy Anh với
ban thieu 2 dau () sau
TestChuoi()
mới đây mà mình thấy bạn đi lẹ hơn minh gắp 3 lần thời gian mình bỏ ra rồi đấy Very good
 
Upvote 0
ban thieu 2 dau () sau
TestChuoi()
Vô Link sau mà Tải help về coi ... help mới nhất đó
http://docs.embarcadero.com/products/rad_studio/
đang coi help thấy hay
ok.PNG
Mã:
procedure TForm2.FormCreate(Sender: TObject);
const
  { Connection string }
  ConnString =
  'Provider=SQLOLEDB.1;Persist Security Info=False;' +
  'User ID=%s;Password=%s;Data Source=%s;Use Procedure for Prepare=1;' +
  'Auto Translate=True;Packet Size=4096;Use Encryption for Data=False;'+
  'Tag with column collation when possible=False';
 
  { SQL Query }
  SQLStr = 'SELECT * FROM customer WHERE customer_id = :AnId;';
 
  { User access }
  UserName = 'db_user_name';
  PassWord = 'db_pass_word';
  Server = 'my.db.server';
 
var
  ADOConn  : TADOConnection;
  ADOQuery : TADOQuery;
  DataSrc  : TDataSource;
  Param    : TParameter;
 
begin
  { Create an ADO connection. }
  ADOConn := TADOConnection.Create(Self);
  { Set up the provider engine }
 
  { Set up the connection string. }
  ADOConn.ConnectionString := Format(ConnString,
    [UserName, PassWord, Server]);
 
  { Disable login prompt. }
  ADOConn.LoginPrompt := False;
 
  try
    ADOConn.Connected := True;
  except
    on e: EADOError do
    begin
      MessageDlg('Error while connecting', mtError,
                  [mbOK], 0);
 
      Exit;
    end;
  end;
 
  { Create the query. }
  ADOQuery := TADOQuery.Create(Self);
  ADOQuery.Connection := ADOConn;
  ADOQuery.SQL.Add(SQLStr);
 
  { Update the parameter that was parsed from the SQL query: AnId. }
  Param := ADOQuery.Parameters.ParamByName('AnId');
  Param.DataType := ftInteger;
  Param.Value := 1;
 
  { Set the query to Prepared--it will improve performance. }
  ADOQuery.Prepared := true;
 
  try
    ADOQuery.Active := True;
  except
    on e: EADOError do
    begin
      MessageDlg('Error while doing query', mtError,
                  [mbOK], 0);
 
      Exit;
    end;
  end;
 
  { Create the data source. }
  DataSrc := TDataSource.Create(Self);
  DataSrc.DataSet := ADOQuery;
  DataSrc.Enabled := true;
 
  { Finally, initialize the grid. }
  DBGrid1.DataSource := DataSrc;
end;
 
Upvote 0
phải nói thật là em cũng chưa biết xài help trong Delphi sao nữa ... bấm cái gì nó ra help ... Em xài bản XE6
tiện đây Anh chỉ Em luôn với

Anh úp cho Em xin cái File help trên máy Anh với
Tôi không dùng các phiên bản mới nên không biết.

Còn khi tôi cài Delphi 5 thì có 2 thư viện sách đồ sộ: Delphi và Windows API. Ngoài ra khi mở Delphi thì icon và menu Help cũng có ngay.

Thôi thì biết tên các hàm rồi thì gõ của bác google thôi.

Thử xem nhé

http://www.mediafire.com/file/9awswaw3zcwhx4u/Help.rar/file

h1.JPG
h2.JPG
h3.JPG
 
Upvote 0
Tôi không dùng các phiên bản mới nên không biết.

Còn khi tôi cài Delphi 5 thì có 2 thư viện sách đồ sộ: Delphi và Windows API. Ngoài ra khi mở Delphi thì icon và menu Help cũng có ngay.

Thôi thì biết tên các hàm rồi thì gõ của bác google thôi.

Thử xem nhé

http://www.mediafire.com/file/9awswaw3zcwhx4u/Help.rar/file

View attachment 205126
View attachment 205127
View attachment 205128
Em mới tải về ok rồi thấy nhiều quá ...
 
Lần chỉnh sửa cuối:
Upvote 0
Web KT
Back
Top Bottom