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

Liên hệ QC

Người dùng đang xem chủ đề này

Nguyễn Duy Tuân

Nghị Hách
Thành viên danh dự
Tham gia
13/6/06
Bài viết
4,842
Được thích
10,337
Giới tính
Nam
Nghề nghiệp
Giáo viên, CEO tại Bluesofts
Lần chỉnh sửa cuối:
Nếu bạn nhận mảng từ GetRows rồi sau đó lại tạo mảng để lưu mới là mất 2 lần làm việc tốc độ sẽ chậm. Giải pháp là không dùng GetRows mà hãy duyệt từng dòng của Recordset rồi lấy vào mảng luôn tốc độ sẽ nhanh.
Chính xác là vậy ... Mình đang tập tành Delphi thì phải tập Ăn cháo xong sau đó mới ăn cơm được chứ ?! :D

Mong các Bạn chỉ thêm 1 vấn đề viết cho Mạnh xin 1 code mẫu vậy là Mạnh từng bước tiếp cận Delphi tốt đó
Cảm ơn rất nhiều
 
Upvote 0
Mạnh mới test lại các kiểu thì thấy hàm đó viết lộn một chút Mạnh điều chỉnh lại như sau mới chạy OK khi ta sử dụng ADO lấy dữ liệu từ 1 Sheet vào Mảng sử dung Phức thức GetRows ... xong dùng hàm chuyển mảng gán lên Range
Mã:
function TransArr(ssArr: OleVariant): OleVariant; stdcall;
var
    tmpArr    : OleVariant;
    x, y    : integer;
    lcol,lRows  : integer;
begin
  lcol := VarArrayHighBound(ssArr, 2); //Cot
  lRows := VarArrayHighBound(ssArr, 1); //dong
  tmpArr := VarArrayCreate([1, lcol + 1, 1, lRows + 1],varVariant);
    for x:= 0 to lcol do begin
        for y:= 0  to lRows do begin
            tmpArr[x + 1, y + 1] := ssArr[y, x];
        end; // y
    end; // x
    Result := tmpArr;
end;
Mô tả sơ bộ 1 chút
1/ Nếu ta ko + thêm 1 trong hàm thì khi lấy lên ta phải cộng thêm 1 khi Resize
Mã:
Range("A2").Resize(UBound(dArr, 1) + 1, UBound(dArr, 2) + 1) = dArr
2/ Còn nếu ta đã cộng thêm 1 trong Hàm TransArr thì khi ta lấy lên gán dữ liệu ko + thêm 1 nữa
Mã:
Range("A2").Resize(UBound(dArr, 1), UBound(dArr, 2)) = dArr
3/ 1 ở đây là 1 cột và 1 dòng

Cảm ơn thuyyeu99 Viết cho Mạnh cái Hàm hay và hay hết tất cả là Mạnh biết xài mảng 2dArray trong Delphi
Mình thấy bạn có máy bài viết Code rất đẹp, mong bạn có cái nào hay chia sẻ với mọi người
 
Upvote 0
Mình đang tập xài thư viện của Windows thử xài Fso trong Delphi mà thấy lỗi Mong các Bạn chỉ dùm
1/ Khởi tạo sử dụng Fso
2/ Giải phóng biến khi thực hiện xong ( Set Fso = nothing ) trên Excel còn trong Delphi giải phóng biến Sao ?!
3/ Code sau chạy làm đơ file Excel ... sai cái gì mong các bạn chỉ dùm ( nó tao xong File D:\MyFile.txt thì thoát luôn Excel )
Mã:
procedure Test_Fso; stdcall;
const
  ForReading = 1;
  ForWriting = 2;
  ForAppending = 8;
  TristateFalse = 0;
var
  f, sPath, fs, objFile : OleVariant;
begin
  sPath := 'D:\MyFile.txt';
  fs := CreateOleObject('Scripting.FileSystemObject');
  if not fs.FileExists(sPath) then
  begin
   objFile := fs.CreateTextFile(sPath);
   objFile.Close();
  end;
  f := fs.OpenTextFile(sPath, ForAppending, TristateFalse);
  f.Write('Hello, world!' + #13#10);
  f.Close();
end;
 
Lần chỉnh sửa cuối:
Upvote 0
Mình đang tập xài thư viện của Windows thử xài Fso trong Delphi mà thấy lỗi Mong các Bạn chỉ dùm
1/ Khởi tạo sử dụng Fso
2/ Giải phóng biến khi thực hiện xong ( Set Fso = nothing ) trên Excel còn trong Delphi giải phóng biến Sao ?!
3/ Code sau chạy làm đơ file Excel ... sai cái gì mong các bạn chỉ dùm ( nó tao xong File D:\MyFile.txt thì thoát luôn Excel )
Mã:
procedure Test_Fso; stdcall;
const
  ForReading = 1;
  ForWriting = 2;
  ForAppending = 8;
  TristateFalse = 0;
var
  f, sPath, fs, objFile : OleVariant;
begin
  sPath := 'D:\MyFile.txt';
  fs := CreateOleObject('Scripting.FileSystemObject');
  if not fs.FileExists(sPath) then
  begin
   objFile := fs.CreateTextFile(sPath);
   objFile.Close();
  end;
  f := fs.OpenTextFile(sPath, ForAppending, TristateFalse);
  f.Write('Hello, world!' + #13#10);
  f.Close();
end;

Set Fso = nothing => fs := Unassigned;

Mã:
  begin
   objFile := fs.CreateTextFile(sPath);
   objFile.WriteToTextFile(sPath, 'Hello, world!' + #13#10, objFile.ctANSI, false);
   objFile.Close;
  end;
or
f.WriteLine('Hello, world!' + #13#10');
f.Close;
 
Upvote 0
Set Fso = nothing => fs := Unassigned;

Mã:
  begin
   objFile := fs.CreateTextFile(sPath);
   objFile.WriteToTextFile(sPath, 'Hello, world!' + #13#10, objFile.ctANSI, false);
   objFile.Close;
  end;
or
f.WriteLine('Hello, world!' + #13#10');
f.Close;
Mới thử xong nó vẫn vậy ... tao file sPath := 'D:\MyFile.txt'; xong nó đơ file Excel xong thoát luôn
Nó sai 1 cái gì đó ... phần uses khai báo là vầy ko biết đúng ko nữa
Mã:
uses
System.win.comobj;

Nếu Mình xài Dic Thì cũng giải phóng biến như Fso hay sao và phần Uses khai báo sao ?
Mã:
Dic := CreateOleObject('Scripting.Dictionary')
Dic := Unassigned ===> Set Dic = Nothing hay sao
 
Lần chỉnh sửa cuối:
Upvote 0
Mới thử xong nó vẫn vậy ... tao file sPath := 'D:\MyFile.txt'; xong nó đơ file Excel xong thoát luôn
Nó sai 1 cái gì đó ... phần uses khai báo là vầy ko biết đúng ko nữa
Mã:
uses
System.win.comobj;

Nếu Mình xài Dic Thì cũng giải phóng biến như Fso hay sao và phần Uses khai báo sao ?
Mã:
Dic := CreateOleObject('Scripting.Dictionary')
Dic := Unassigned ===> Set Dic = Nothing hay sao
Ủa mình chạy đâu thấy lỗi đâu ta
User ComObj
may cai CreateOleObject('Scripting.Dictionary') minh khong co dung
ban than Delphi hinh nhu cung co Dic ay
Generics Collections TDictionary

System.Variants.Unassigned

Returns an "empty" variant.

A variant variable can be "empty", meaning it has not yet been assigned to. The Unassigned function returns an empty variant, which can be assigned to a variant variable to restore the variable to its initial state.

Use the VarIsEmpty function to test whether a variant is empty. When used on an empty variant, the VarType standard function returns varEmpty.

If an empty variant is cast to another type (for example, by assigning to a non-variant variable or calling VarAsType) the following conversions occur:
Note: Unassigned is useful with variants referencing OLE Automation Objects that you want to keep "alive" until another value is assigned to the variant.
 
Lần chỉnh sửa cuối:
Upvote 0
Ủa mình chạy đâu thấy lỗi đâu ta
User ComObj
may cai CreateOleObject('Scripting.Dictionary') minh khong co dung
ban than Delphi hinh nhu cung co Dic ay
Generics Collections TDictionary

System.Variants.Unassigned

Returns an "empty" variant.

A variant variable can be "empty", meaning it has not yet been assigned to. The Unassigned function returns an empty variant, which can be assigned to a variant variable to restore the variable to its initial state.

Use the VarIsEmpty function to test whether a variant is empty. When used on an empty variant, the VarType standard function returns varEmpty.

If an empty variant is cast to another type (for example, by assigning to a non-variant variable or calling VarAsType) the following conversions occur:
Note: Unassigned is useful with variants referencing OLE Automation Objects that you want to keep "alive" until another value is assigned to the variant.
Mới thử add vào mà ko biết xài kiểu gì nữa :D:D

Fso2.PNGFuncti.PNG

Thấy có dòng sau nói
Lưu ý: Unassigned là hữu ích với các biến thể tham chiếu OLE Automation Objects mà bạn muốn giữ "alive" giá trị khác được gán cho biến thể.
Giải phóng biến Object đó he Set Fso = Nothing
 
Lần chỉnh sửa cuối:
Upvote 0
Mới thử add vào mà ko biết xài kiểu gì nữa :D:D

View attachment 204532View attachment 204533

Thấy có dòng sau nói
Lưu ý: Unassigned là hữu ích với các biến thể tham chiếu OLE Automation Objects mà bạn muốn giữ "alive" giá trị khác được gán cho biến thể.
Giải phóng biến Object đó he Set Fso = Nothing
bạn dùng CreateOleObject('Scripting.Dictionary') đưa ví dụ lên đây mình mò thử
 
Upvote 0
bạn dùng CreateOleObject('Scripting.Dictionary') đưa ví dụ lên đây mình mò thử
Giờ ta thử làm 1 cái Dic xem tình hình sao nhé ... bước đầu ta làm đơn giản xong ... sẻ làm phức tạp từ từ
1/ Có vùng dữ liệu đưa vào mảng là : Arr = Range("B4:E1000").value
2/ Ta sử dụng Dic lọc duy nhất Cột B xong Gán kết qủa qua cột [H4]
3/ Ta sử dụng thêm điều kiện nếu Cột B có dự liệu thì lấy nguyên dòng đó Nếu ko thì bỏ qua

Nếu trên VBA thì Mạnh hay xài vầy
Mã:
If Len(Arr(i, 1)) Then

Còn Delphi Mạnh đoán vậy hên thì trúng he
Mã:
If Length(Arr(i,1))then
4/ qua bài cơ bản này xong sẻ làm phức tạp rắc rối thêm 1 chút .... quan trọng là biết xài Dic trong Delphi cái Đã xong tính tiếp

Cảm ơn Bạn và rất mong từng bước chỉ Mạnh Tiếp cận Delphi qua các Code cơ bản nhất ... Thì Mạnh sẻ học tốt đó
Capture.PNG
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Giờ ta thử làm 1 cái Dic xem tình hình sao nhé ... bước đầu ta làm đơn giản xong ... sẻ làm phức tạp từ từ
1/ Có vùng dữ liệu đưa vào mảng là : Arr = Range("B4:E1000").value
2/ Ta sử dụng Dic lọc duy nhất Cột B xong Gán kết qủa qua cột [H4]
3/ Ta sử dụng thêm điều kiện nếu Cột B có dự liệu thì lấy nguyên dòng đó Nếu ko thì bỏ qua

Nếu trên VBA thì Mạnh hay xài vầy
Mã:
If Len(Arr(i, 1)) Then

Còn Delphi Mạnh đoán vậy hên thì trúng he
Mã:
If Length(Arr(i,1))then
4/ qua bài cơ bản này xong sẻ làm phức tạp rắc rối thêm 1 chút .... quan trọng là biết xài Dic trong Delphi cái Đã xong tính tiếp

Cảm ơn Bạn và rất mong từng bước chỉ Mạnh Tiếp cận Delphi qua các Code cơ bản nhất ... Thì Mạnh sẻ học tốt đó
View attachment 204558
Mạnh cụ thể bằng Code VBA đi để làm cho đúng ý (cái này chắc bạn làm trong 30s), tự trong Delphi mình không dùng Dic mà dùng TStringList đỡ mắc công suy nghĩ hihihihihi
 
Upvote 0
Mạnh cụ thể bằng Code VBA đi để làm cho đúng ý (cái này chắc bạn làm trong 30s), tự trong Delphi mình không dùng Dic mà dùng TStringList đỡ mắc công suy nghĩ hihihihihi
Dic trên VBA thì đơn giản mà .... khó khăn và quan trọng nhất là tùy biến thuật toán link tinh trong đó thui ... còn lọc duy nhất đầy cách viết
Mã:
Sub Test_Dic()
    Dim Arr(), Res(), i As Long, k As Long
    Arr = Range("B4:E1000").Value
    ReDim Res(1 To UBound(Arr, 1), 1 To UBound(Arr, 2))
    With CreateObject("scripting.dictionary")
        For i = 1 To UBound(Arr, 1)
            If Len(Arr(i, 1)) Then
                If Not .Exists(Arr(i, 1)) Then
                    k = k + 1
                    .Add Arr(i, 1), k
                    Res(k, 1) = Arr(i, 1)
                    Res(k, 2) = Arr(i, 2)
                    Res(k, 3) = Arr(i, 3)
                    Res(k, 4) = Arr(i, 4)
                End If
            End If
        Next
        Range("H4:M65536").ClearContents
        Range("H4").Resize(UBound(Arr, 1), UBound(Arr, 2)) = Res
    End With
End Sub
 
Upvote 0
Giờ ta thử làm 1 cái Dic xem tình hình sao nhé ... bước đầu ta làm đơn giản xong ... sẻ làm phức tạp từ từ
1/ Có vùng dữ liệu đưa vào mảng là : Arr = Range("B4:E1000").value
2/ Ta sử dụng Dic lọc duy nhất Cột B xong Gán kết qủa qua cột [H4]
3/ Ta sử dụng thêm điều kiện nếu Cột B có dự liệu thì lấy nguyên dòng đó Nếu ko thì bỏ qua

Nếu trên VBA thì Mạnh hay xài vầy
Mã:
If Len(Arr(i, 1)) Then

Còn Delphi Mạnh đoán vậy hên thì trúng he
Mã:
If Length(Arr(i,1))then
4/ qua bài cơ bản này xong sẻ làm phức tạp rắc rối thêm 1 chút .... quan trọng là biết xài Dic trong Delphi cái Đã xong tính tiếp

Cảm ơn Bạn và rất mong từng bước chỉ Mạnh Tiếp cận Delphi qua các Code cơ bản nhất ... Thì Mạnh sẻ học tốt đó
View attachment 204558
Mạnh chính sửa cho phù hợp với mình nhé
Mã:
procedure TForm1.Button24Click(Sender: TObject);
var
    Src,Des, Tmp,Dic,Arr: OleVariant;
    i, j,n,n1,lcol,lRows: Longint;
    TG: Double;
begin
   try
    E := GetActiveOleObject('Excel.Application');
  except
   ShowMessage('khong lay duoc excel ?');
  end;
 Dic := CreateOleObject('Scripting.Dictionary') ;
    j := 0;
     Src  := E.Range['A4:E100'].Value;
      Des  := E.Range['H4'];
      lcol := VarArrayHighBound(Src, 2); //Cot
      lRows := VarArrayHighBound(Src, 1); //dong
       Arr := VarArrayCreate([1, lcol + 1, 1, lRows + 1],varVariant);
   for i:=VarArrayLowBound(Src, 1) to VarArrayHighBound(Src,1) do begin
    if Src[i, 2]<>'' then begin
            Tmp := Src[i, 2]; // Src(i, 1) & Src(i, 2)
            if  not dic.Exists(Tmp) then begin
                j := j+1;
                Dic.Add(Tmp, '');
                Arr[1, j] := Src[i, 1];
                Arr[2, j] := Src[i, 2];
            end;
        end;
    end;
     if j<>0 then begin
    for n:=VarArrayLowBound(Arr, 2) to VarArrayHighBound(Arr,2) do begin
     Des.Cells.Item[n+1, 1].Value:=Arr[2,n];
    end;
    end;
end;
 
Upvote 0
Mạnh chính sửa cho phù hợp với mình nhé
Mã:
procedure TForm1.Button24Click(Sender: TObject);
var
    Src,Des, Tmp,Dic,Arr: OleVariant;
    i, j,n,n1,lcol,lRows: Longint;
    TG: Double;
begin
   try
    E := GetActiveOleObject('Excel.Application');
  except
   ShowMessage('khong lay duoc excel ?');
  end;
Dic := CreateOleObject('Scripting.Dictionary') ;
    j := 0;
     Src  := E.Range['A4:E100'].Value;
      Des  := E.Range['H4'];
      lcol := VarArrayHighBound(Src, 2); //Cot
      lRows := VarArrayHighBound(Src, 1); //dong
       Arr := VarArrayCreate([1, lcol + 1, 1, lRows + 1],varVariant);
   for i:=VarArrayLowBound(Src, 1) to VarArrayHighBound(Src,1) do begin
    if Src[i, 2]<>'' then begin
            Tmp := Src[i, 2]; // Src(i, 1) & Src(i, 2)
            if  not dic.Exists(Tmp) then begin
                j := j+1;
                Dic.Add(Tmp, '');
                Arr[1, j] := Src[i, 1];
                Arr[2, j] := Src[i, 2];
            end;
        end;
    end;
     if j<>0 then begin
    for n:=VarArrayLowBound(Arr, 2) to VarArrayHighBound(Arr,2) do begin
     Des.Cells.Item[n+1, 1].Value:=Arr[2,n];
    end;
    end;
end;
1/ nếu xài dòng sau không hiểu sao nó làm đơ file Excel xong thoát luôn
Mã:
E := GetActiveOleObject('Excel.Application');

2/ Mạnh chỉnh lại vào chạy Tuyệt vời tuy nhiên kết quả sai 1 chút do mấy vòng For kia sai 1 tẹo chỉnh lại chút là Ok
Mã:
procedure Test_Dic(Src, Des: OleVariant);stdcall;
var
    //Src,
    //Des,
    Tmp,Dic,Arr: OleVariant;
    i, j,n,n1,lcol,lRows: Longint;
    TG: Double;
    //E: OleVariant;
begin
   //try
    //E := GetActiveOleObject('Excel.Application');
  //except
   //ShowMessage('khong lay duoc excel ?');
  //end;
Dic := CreateOleObject('Scripting.Dictionary') ;
    j := 0;
     //Src  := E.Range['A4:E100'].Value;
     //Src  := Range['A4:E100'];
     // Des  := Range['H4'];
      lcol := VarArrayHighBound(Src, 2); //Cot
      lRows := VarArrayHighBound(Src, 1); //dong
       Arr := VarArrayCreate([1, lcol + 1, 1, lRows + 1],varVariant);
   for i:=VarArrayLowBound(Src, 1) to VarArrayHighBound(Src,1) do begin
    if Src[i, 2]<>'' then begin
            Tmp := Src[i, 2]; // Src(i, 1) & Src(i, 2)
            if  not dic.Exists(Tmp) then begin
                j := j+1;
                Dic.Add(Tmp, '');
                Arr[1, j] := Src[i, 1];
                Arr[2, j] := Src[i, 2];
            end;
        end;
    end;
     if j<>0 then begin
    for n:=VarArrayLowBound(Arr, 2) to VarArrayHighBound(Arr,2) do begin
     //Des.Cells.Item[n+1, 1].Value:=Arr[2,n];    //Bao Loi Value
     Des.Cells.Item[n+1, 1]:=Arr[2,n];
    end;
    end;
end;
Giờ lại bận rồi Mai sáng mạnh viết lại thành 1 Function là là tuyệt Vời

3/ Trên VBA ta xài Resize nhhu7 sau còn trong Delphi code nào thay thế như vậy Bạn Nhỉ
Mã:
Range("H4").Resize(UBound(Arr, 1), UBound(Arr, 2)) = Res

hay đó Mai mạnh Nghiên Cứu Kỹ hơn .... Cảm ơn rất NhiềuCapture.PNG

Có lẻ truyền chính tham số từ Excel vào nó tương tác với *.dll cho nên nó chạy rất nhanh thấy bài trước @Nguyễn Duy Tuân có nói ?!
 
Lần chỉnh sửa cuối:
Upvote 0
1/ nếu xài dòng sau không hiểu sao nó làm đơ file Excel xong thoát luôn
Mã:
E := GetActiveOleObject('Excel.Application');

2/ Mạnh chỉnh lại vào chạy Tuyệt vời tuy nhiên kết quả sai 1 chút do mấy vòng For kia sai 1 tẹo chỉnh lại chút là Ok
Mã:
procedure Test_Dic(Src, Des: OleVariant);stdcall;
var
    //Src,
    //Des,
    Tmp,Dic,Arr: OleVariant;
    i, j,n,n1,lcol,lRows: Longint;
    TG: Double;
    //E: OleVariant;
begin
   //try
    //E := GetActiveOleObject('Excel.Application');
  //except
   //ShowMessage('khong lay duoc excel ?');
  //end;
Dic := CreateOleObject('Scripting.Dictionary') ;
    j := 0;
     //Src  := E.Range['A4:E100'].Value;
     //Src  := Range['A4:E100'];
     // Des  := Range['H4'];
      lcol := VarArrayHighBound(Src, 2); //Cot
      lRows := VarArrayHighBound(Src, 1); //dong
       Arr := VarArrayCreate([1, lcol + 1, 1, lRows + 1],varVariant);
   for i:=VarArrayLowBound(Src, 1) to VarArrayHighBound(Src,1) do begin
    if Src[i, 2]<>'' then begin
            Tmp := Src[i, 2]; // Src(i, 1) & Src(i, 2)
            if  not dic.Exists(Tmp) then begin
                j := j+1;
                Dic.Add(Tmp, '');
                Arr[1, j] := Src[i, 1];
                Arr[2, j] := Src[i, 2];
            end;
        end;
    end;
     if j<>0 then begin
    for n:=VarArrayLowBound(Arr, 2) to VarArrayHighBound(Arr,2) do begin
     //Des.Cells.Item[n+1, 1].Value:=Arr[2,n];    //Bao Loi Value
     Des.Cells.Item[n+1, 1]:=Arr[2,n];
    end;
    end;
end;
Giờ lại bận rồi Mai sáng mạnh viết lại thành 1 Function là là tuyệt Vời

3/ Trên VBA ta xài Resize nhhu7 sau còn trong Delphi code nào thay thế như vậy Bạn Nhỉ
Mã:
Range("H4").Resize(UBound(Arr, 1), UBound(Arr, 2)) = Res

hay đó Mai mạnh Nghiên Cứu Kỹ hơn .... Cảm ơn rất NhiềuView attachment 204577

Có lẻ truyền chính tham số từ Excel vào nó tương tác với *.dll cho nên nó chạy rất nhanh thấy bài trước @Nguyễn Duy Tuân có nói ?!
Tự mình copy cai UDF của mạnh phía trên nên nó hơi rối tý hihihi

lcol := VarArrayHighBound(Src, 2); //Cot
lRows := VarArrayHighBound(Src, 1); //dong
//Arr := VarArrayCreate([1, lcol + 1, 1, lRows + 1],varVariant);
Arr := VarArrayCreate([1, lRows + 1, 1, lcol + 1],varVariant);

Arr[j, 1] := Src[i, 1];
Arr[j, 2] := Src[i, 2];


Des.Resize[j, VarArrayHighBound(Arr, 2)].Value:=Arr;
 
Upvote 0
Tự mình copy cai UDF của mạnh phía trên nên nó hơi rối tý hihihi

lcol := VarArrayHighBound(Src, 2); //Cot
lRows := VarArrayHighBound(Src, 1); //dong
//Arr := VarArrayCreate([1, lcol + 1, 1, lRows + 1],varVariant);
Arr := VarArrayCreate([1, lRows + 1, 1, lcol + 1],varVariant);

Arr[j, 1] := Src[i, 1];
Arr[j, 2] := Src[i, 2];


Des.Resize[j, VarArrayHighBound(Arr, 2)].Value:=Arr;
Cũng code đó bạn viết cho Mình xin Tổng hợp cộng lại cột E theo mã hàng cột B

Về Dic như vậy Cơ bản Mạnh đã học xong ... mai mốt chuyển qua cái khác Mong Bạn chỉ cho mạnh học với nhé

Mỗi một lĩnh vực Mạnh xin 1 code cơ bản vậy là tuyệt Vời .... 6 tháng sau sẻ bắt đầu nhập Môn Delphi ok đó
 
Upvote 0
1/ nếu xài dòng sau không hiểu sao nó làm đơ file Excel xong thoát luôn
Mã:
E := GetActiveOleObject('Excel.Application');


hay đó Mai mạnh Nghiên Cứu Kỹ hơn .... Cảm ơn rất NhiềuView attachment 204577

Có lẻ truyền chính tham số từ Excel vào nó tương tác với *.dll cho nên nó chạy rất nhanh thấy bài trước @Nguyễn Duy Tuân có nói ?!

Nếu viết phần mềm độc lập - Application thì ta chủ động tạo một instance của Excel là cần. Dùng GetActiveOleObject hay CreateOleObject để gọi "Excel.Application" tùy vào mục đích. Nhưng khi viết DLL, OCX thì ta đã xác định nó được gọi bên trong một Application cụ thể rồi vì thế vai trò của hàm chỉ đảm nhận khai thác từ tham số truyền vào và trả về cái người gọi cần. Nên việc viết hàm phải rất chú ý tới cách tạo , truyền tham số, trả về.

Có một điều nữa là Delphi có tất cả những thứ cần thiết để làm những yêu cầu mà các bạn lập trình VBA hay dùng như Dictionary, ADO, FileSystemObject. Nên hãy dùng những thứ trong Delphi gần như sẽ là tốt và chủ động nhất, trừ phi không có.

Dùng những Object thứ có sẵn trong Delphi phần lớn sẽ rất nhanh vì họ làm công nghệ mới, cải tiến rất nhiều, nhiều hàm hệ thống Delphi cung cấp họ viết bằng Assemply tốc độ chạy rất nhanh.
 
Upvote 0
Nếu viết phần mềm độc lập - Application thì ta chủ động tạo một instance của Excel là cần. Dùng GetActiveOleObject hay CreateOleObject để gọi "Excel.Application" tùy vào mục đích. Nhưng khi viết DLL, OCX thì ta đã xác định nó được gọi bên trong một Application cụ thể rồi vì thế vai trò của hàm chỉ đảm nhận khai thác từ tham số truyền vào và trả về cái người gọi cần. Nên việc viết hàm phải rất chú ý tới cách tạo , truyền tham số, trả về.

Có một điều nữa là Delphi có tất cả những thứ cần thiết để làm những yêu cầu mà các bạn lập trình VBA hay dùng như Dictionary, ADO, FileSystemObject. Nên hãy dùng những thứ trong Delphi gần như sẽ là tốt và chủ động nhất, trừ phi không có.

Dùng những Object thứ có sẵn trong Delphi phần lớn sẽ rất nhanh vì họ làm công nghệ mới, cải tiến rất nhiều, nhiều hàm hệ thống Delphi cung cấp họ viết bằng Assemply tốc độ chạy rất nhanh.
Nếu được bạn cho Mình xin 1 code không phải khai báo như sau với để Mình học ..
Mã:
Dic := CreateOleObject('Scripting.Dictionary') ;
Mình suy đoán nếu ko khởi tạo CreateOleObject thì sẻ cho tốc độ nhanh hơn đó vì ADO Delphi thấy cũng tích hợp sẳn dòng sau
Mã:
cnn := TADOConnection.Create(nil);
Có nghĩa họ viết cho Windows nên đã tích hợp sẳn luôn trong đó ko cần khởi tạo nữa ( mạnh suy đoán bạy vậy)
 
Upvote 0
Nếu được bạn cho Mình xin 1 code không phải khai báo như sau với để Mình học ..
Mã:
Dic := CreateOleObject('Scripting.Dictionary') ;
Mình suy đoán nếu ko khởi tạo CreateOleObject thì sẻ cho tốc độ nhanh hơn đó vì ADO Delphi thấy cũng tích hợp sẳn dòng sau
Mã:
cnn := TADOConnection.Create(nil);
Có nghĩa họ viết cho Windows nên đã tích hợp sẳn luôn trong đó ko cần khởi tạo nữa ( mạnh suy đoán bạy vậy)
nếu bạn dùng ADO trong Delphi thử nghiên cứu xem có câu lệnh sụm theo điều kiện đấy, tất cả yêu cầu của bạn điều có trong sql (Có đợt tôi làm chương trình quản lý hóa đơn bằng C Shap cũng na ná delphi cũng dùng Sql, giờ máy không còn cai nên không mở Code lên được, ban thu nghiên cứu xem)
 
Lần chỉnh sửa cuối:
Upvote 0
Nếu được bạn cho Mình xin 1 code không phải khai báo như sau với để Mình học ..
Mã:
Dic := CreateOleObject('Scripting.Dictionary') ;
Mình suy đoán nếu ko khởi tạo CreateOleObject thì sẻ cho tốc độ nhanh hơn đó vì ADO Delphi thấy cũng tích hợp sẳn dòng sau
Mã:
cnn := TADOConnection.Create(nil);
Có nghĩa họ viết cho Windows nên đã tích hợp sẳn luôn trong đó ko cần khởi tạo nữa ( mạnh suy đoán bạy vậy)

Cách làm việc với Dictionary trong Delphi là dùng đối tượng TDictionary, đối tượng này nằm trong unit System.Generics.Collections.
Bạn hãy tạo một VCL Application rồi copy đoạn code dưới đây để chạy.


Mã:
uses System.Generics.Collections;
type
  TMyData = class
    MaNV: string;
    TenNV: string;
    Tuoi: Integer;
  end;
procedure TForm1.FormCreate(Sender: TObject);

var
  Key: string;
  data: TMyData;
  dic: TDictionary<string, TMyData>;
  I: Integer;
begin
  dic := TDictionary<string, TMyData>.create;
  try
    data := TMyData.Create;
    data.MaNV := '001';
    data.TenNV := 'Nguyen Duy Tuan';
    data.Tuoi := 25;
    dic.Add('001', data); //add data to dictionary

    data := TMyData.Create;
    data.MaNV := '001';
    data.TenNV := 'Nguyen Bao Ninh';
    data.Tuoi := 24;
    dic.Add('002', data); //add data to dictionary

    //kiem tra ton tai key chua
    Key := '001';
    if dic.ContainsKey(Key) then
    begin
      data := dic.Items[Key];
      ShowMessage('Da co MaNV da ton tai voi ten NV: ' + data.TenNV);
    end
    else
    begin
      ShowMessage('Chua co can them moi!');
    end;

    //doc tung ban ghi (record) vaf free
    for data in Dic.Values do
    begin
      ShowMessage('Da co MaNV da ton tai voi ten NV: ' + data.TenNV);
      //Free memory
      data.Free;
    end;
  finally
    dic.Free;
  end;
end;
 
Lần chỉnh sửa cuối:
Upvote 0
Cách làm việc với Dictionary trong Delphi là dùng đối tượng TDictionary, đối tượng này nằm trong unit System.Generics.Collections.
Bạn hãy tạo một VCL Application rồi copy đoạn code dưới đây để chạy.


Mã:
uses System.Generics.Collections;
type
  TMyData = class
    MaNV: string;
    TenNV: string;
    Tuoi: Integer;
  end;
procedure TForm1.FormCreate(Sender: TObject);

var
  Key: string;
  data: TMyData;
  dic: TDictionary<string, TMyData>;
  I: Integer;
begin
  dic := TDictionary<string, TMyData>.create;
  try
    data := TMyData.Create;
    data.MaNV := '001';
    data.TenNV := 'Nguyen Duy Tuan';
    data.Tuoi := 25;
    dic.Add('001', data); //add data to dictionary

    data := TMyData.Create;
    data.MaNV := '001';
    data.TenNV := 'Nguyen Bao Ninh';
    data.Tuoi := 24;
    dic.Add('002', data); //add data to dictionary

    //kiem tra ton tai key chua
    Key := '001';
    if dic.ContainsKey(Key) then
    begin
      data := dic.Items[Key];
      ShowMessage('Da co MaNV da ton tai voi ten NV: ' + data.TenNV);
    end
    else
    begin
      ShowMessage('Chua co can them moi!');
    end;

    //doc tung ban ghi (record) vaf free
    for data in Dic.Values do
    begin
      ShowMessage('Da co MaNV da ton tai voi ten NV: ' + data.TenNV);
      //Free memory
      data.Free;
    end;
  finally
    dic.Free;
  end;
end;
Cảm ơn bạn vậy là mình đoán trúng :D ... vốn dĩ khởi tạo Obiect nó đã nhanh rồi mà xài kiểu này nó lại nhanh nữa
Mình có coi mấy trang nước ngoài thấy nó keo xài API của windows trong Delphi càng tiện hơn nữa
Khai Báo Uses
Mã:
uses
ShellApi,
vậy là xài nó đơn giản như sau ... quá tiện đi chứ
Mã:
begin
   ShellExecute(0, 'open', PCHAR(SaveDialog.FileName), nil, nil, SW_SHOWNORMAL);
end;
Còn cách trên của Bạn Mạnh nghỉ Dic với Fso chung một thư viên Windows Xài Fso cũng khai báo như vậy hay khác mong Bạn chỉ cho
Xin cảm ơn
 
Upvote 0
Cách làm việc với Dictionary trong Delphi là dùng đối tượng TDictionary, đối tượng này nằm trong unit System.Generics.Collections.
Bạn hãy tạo một VCL Application rồi copy đoạn code dưới đây để chạy.


Mã:
uses System.Generics.Collections;
type
  TMyData = class
    MaNV: string;
    TenNV: string;
    Tuoi: Integer;
  end;
procedure TForm1.FormCreate(Sender: TObject);

var
  Key: string;
  data: TMyData;
  dic: TDictionary<string, TMyData>;
  I: Integer;
begin
  dic := TDictionary<string, TMyData>.create;
  try
    data := TMyData.Create;
    data.MaNV := '001';
    data.TenNV := 'Nguyen Duy Tuan';
    data.Tuoi := 25;
    dic.Add('001', data); //add data to dictionary

    data := TMyData.Create;
    data.MaNV := '001';
    data.TenNV := 'Nguyen Bao Ninh';
    data.Tuoi := 24;
    dic.Add('002', data); //add data to dictionary

    //kiem tra ton tai key chua
    Key := '001';
    if dic.ContainsKey(Key) then
    begin
      data := dic.Items[Key];
      ShowMessage('Da co MaNV da ton tai voi ten NV: ' + data.TenNV);
    end
    else
    begin
      ShowMessage('Chua co can them moi!');
    end;

    //doc tung ban ghi (record) vaf free
    for data in Dic.Values do
    begin
      ShowMessage('Da co MaNV da ton tai voi ten NV: ' + data.TenNV);
      //Free memory
      data.Free;
    end;
  finally
    dic.Free;
  end;
end;
Sẵn tiện anh làm sum luôn đi
 
Upvote 0
Sẵn tiện anh làm sum luôn đi

Nếu làm về CSDL thì dùng SQL, như vậy cách để SUM thì dùng trong ngôn ngữ SQL. ADOConnection là object để thực thi nó (thực ra có nhiều cái khác nhưng tạm cứ dùng cái này cho người làm VBA gần gũi mà thôi).

Câu lệnh để tính SUM là

ADOQuery1.SQL.Text := ' SELECT MAHH, SUM(SLG) AS [SLG] FROM KHO GROUP BY MAHH";

Duyệt từng dòng trong ADOQuery1 như sau:

while not ADOQuery1.Eof do
begin
data.MAHH := ADOQuery1.Fields[0].AsString;
data.SLG := ADOQuery1.Fields[0].AsFloat;
ADOQuery1.Next;
end;

...

Không biết có phải ý bạn là thế không?
 
Upvote 0
Sẵn tiện anh làm sum luôn đi
bạn thử code trong Delphi xem sao Nhé
1/ Theo Cách Bạn viết
2/ Theo hướng Dẫn bài 124
Mã:
Sub Test_Dic_Sum()
    Dim i As Long, Arr(), Res(), k As Long, x As Long
    Arr = Range("B4:E1000").Value
    ReDim Res(1 To UBound(Arr, 1), 1 To UBound(Arr, 2))
    With CreateObject("scripting.dictionary")
        For i = 1 To UBound(Arr)
            If Len(Arr(i, 1)) Then
                If Not .exists(Arr(i, 1)) Then
                    k = k + 1
                    .Add Arr(i, 1), k
                    Res(k, 1) = Arr(i, 1)
                    Res(k, 2) = Arr(i, 2)
                    Res(k, 3) = Arr(i, 3)
                    Res(k, 4) = Arr(i, 4)
                Else
                    x = .Item(Arr(i, 1))
                    Res(x, 4) = Res(x, 4) + Arr(i, 4)
                End If
            End If
        Next
        Range("H4").Resize(k, 4) = Res
    End With
End Sub
 
Upvote 0
Nếu làm về CSDL thì dùng SQL, như vậy cách để SUM thì dùng trong ngôn ngữ SQL. ADOConnection là object để thực thi nó (thực ra có nhiều cái khác nhưng tạm cứ dùng cái này cho người làm VBA gần gũi mà thôi).

Câu lệnh để tính SUM là

ADOQuery1.SQL.Text := ' SELECT MAHH, SUM(SLG) AS [SLG] FROM KHO GROUP BY MAHH";

Duyệt từng dòng trong ADOQuery1 như sau:

while not ADOQuery1.Eof do
begin
data.MAHH := ADOQuery1.Fields[0].AsString;
data.SLG := ADOQuery1.Fields[0].AsFloat;
ADOQuery1.Next;
end;

...

Không biết có phải ý bạn là thế không?
Sai Sql thống kê với tính toán là nhanh gọn lẹ, còn cách nào không dùng Sql hay hay anh Tuân cho gợi ý với hihihih
 
Upvote 0
Các bạn lưu ý là. Khai thác tối đa thư viện có trong Delphi vì người ta làm để chạy trên các nền tảng Linux, MAC OS, Windows, Android, iOS nên chỉ cần một code ta sẽ build ra các loại ứng dụng đó. Còn khi phải dùng cả những DLL của Microsoft cần lắm mới dùng vì nó đồng nghĩa xác định ứng dụng của bạn chỉ chạy trong Windows mà thôi.

Microsoft (MS) là hãng cộng nghệ nổi tiếng nhưng trong mắt tôi thì họ chỉ là một trong số nhiều hãng khác, MS không phải là nhất tất cả, đặc biệt công nghệ của họ (hiện nay) không phải định hướng cho multi platforms - đây là xu thế toàn cầu hóa.
Bài đã được tự động gộp:

Sai Sql thống kê với tính toán là nhanh gọn lẹ, còn cách nào không dùng Sql hay hay anh Tuân cho gợi ý với hihihih

Dùng theo cách của Dictionary thôi chứ không có gì ảo thuật nữa :).
Bài đã được tự động gộp:

Cảm ơn bạn vậy là mình đoán trúng :D ... vốn dĩ khởi tạo Obiect nó đã nhanh rồi mà xài kiểu này nó lại nhanh nữa
Còn cách trên của Bạn Mạnh nghỉ Dic với Fso chung một thư viên Windows Xài Fso cũng khai báo như vậy hay khác mong Bạn chỉ cho
Xin cảm ơn

Làm việc với ổ đĩa, file, folder thì đừng dùng FSO như VBA nhé. Hãy dùng các hàm trong Delphi rất tốt đó - Nó còn là Multi Platforms.
Bạn dùng tới cái gì thì cứ gõ từ khóa Google, ví dụ "How to check file exists" + Delphi. Nếu thấy tiếng Anh khó thì nhờ Google dịch cho, Tất cả đều có ví dụ hết rồi.
 
Lần chỉnh sửa cuối:
Upvote 0
bạn thử code trong Delphi xem sao Nhé
1/ Theo Cách Bạn viết
2/ Theo hướng Dẫn bài 124
Mã:
Sub Test_Dic_Sum()
    Dim i As Long, Arr(), Res(), k As Long, x As Long
    Arr = Range("B4:E1000").Value
    ReDim Res(1 To UBound(Arr, 1), 1 To UBound(Arr, 2))
    With CreateObject("scripting.dictionary")
        For i = 1 To UBound(Arr)
            If Len(Arr(i, 1)) Then
                If Not .exists(Arr(i, 1)) Then
                    k = k + 1
                    .Add Arr(i, 1), k
                    Res(k, 1) = Arr(i, 1)
                    Res(k, 2) = Arr(i, 2)
                    Res(k, 3) = Arr(i, 3)
                    Res(k, 4) = Arr(i, 4)
                Else
                    x = .Item(Arr(i, 1))
                    Res(x, 4) = Res(x, 4) + Arr(i, 4)
                End If
            End If
        Next
        Range("H4").Resize(k, 4) = Res
    End With
End Sub
Muốn thì làm luôn

Mã:
procedure TForm1.Button24Click(Sender: TObject);
var
    Src,Des, Tmp,Dic,Arr,Rng: OleVariant;
    i, j,n,n1,lcol,lRows,dongcuoi,x: Longint;
    TG: Double;
  temp,key: string;
  Start: Cardinal;
begin
Start := GetTickCount;
   try
    E := GetActiveOleObject('Excel.Application');

  except
   ShowMessage('khong lay duoc excel ?');
  end;
  Dic := CreateOleObject('Scripting.Dictionary') ;
    j := 0;
  Src  := E.Range['A4:E20'].Value;
  Des  := E.Range['H4'];
  lcol := VarArrayHighBound(Src, 2); //Cot
  lRows := VarArrayHighBound(Src, 1); //dong
  Arr := VarArrayCreate([1, lRows + 1, 1, lcol + 1],varVariant);
   for i:=VarArrayLowBound(Src, 1) to VarArrayHighBound(Src,1) do begin
    if Src[i, 2]<>'' then begin
          Tmp := Src[i, 2];
            if  not dic.Exists(Tmp) then begin
                j := j+1;
                Dic.Add(Tmp, j);
                 Arr[j, 1] := Src[i, 1];
                 Arr[j, 2] := Src[i, 2];
        Arr[j, 3] := Src[i, 3];
        Arr[j, 4] := Src[i, 4];
        Arr[j, 5] := Src[i, 5];
        end else begin
        x := Dic.Item[Src[i, 2]];
        Arr[x, 5] := IntToStr(StrToIntDef(Trim(VarToStr(Arr[x, 5])), 0) + StrToIntDef(Trim(VarToStr(Src[i, 5])), 0));
            end;
        end;
    end;
     if j<>0 then begin
    Des.Resize[j, VarArrayHighBound(Arr, 2)].Value:=Arr;
    end;
   ShowMessage(Format('Thời gian lọc là : %d ms', [GetTickCount - Start]));
end;
 
Upvote 0
Muốn thì làm luôn

Mã:
procedure TForm1.Button24Click(Sender: TObject);
var
    Src,Des, Tmp,Dic,Arr,Rng: OleVariant;
    i, j,n,n1,lcol,lRows,dongcuoi,x: Longint;
    TG: Double;
  temp,key: string;
  Start: Cardinal;
begin
Start := GetTickCount;
   try
    E := GetActiveOleObject('Excel.Application');

  except
   ShowMessage('khong lay duoc excel ?');
  end;
  Dic := CreateOleObject('Scripting.Dictionary') ;
    j := 0;
  Src  := E.Range['A4:E20'].Value;
  Des  := E.Range['H4'];
  lcol := VarArrayHighBound(Src, 2); //Cot
  lRows := VarArrayHighBound(Src, 1); //dong
  Arr := VarArrayCreate([1, lRows + 1, 1, lcol + 1],varVariant);
   for i:=VarArrayLowBound(Src, 1) to VarArrayHighBound(Src,1) do begin
    if Src[i, 2]<>'' then begin
          Tmp := Src[i, 2];
            if  not dic.Exists(Tmp) then begin
                j := j+1;
                Dic.Add(Tmp, j);
                 Arr[j, 1] := Src[i, 1];
                 Arr[j, 2] := Src[i, 2];
        Arr[j, 3] := Src[i, 3];
        Arr[j, 4] := Src[i, 4];
        Arr[j, 5] := Src[i, 5];
        end else begin
        x := Dic.Item[Src[i, 2]];
        Arr[x, 5] := IntToStr(StrToIntDef(Trim(VarToStr(Arr[x, 5])), 0) + StrToIntDef(Trim(VarToStr(Src[i, 5])), 0));
            end;
        end;
    end;
     if j<>0 then begin
    Des.Resize[j, VarArrayHighBound(Arr, 2)].Value:=Arr;
    end;
   ShowMessage(Format('Thời gian lọc là : %d ms', [GetTickCount - Start]));
end;
Thử 1 code theo hướng dẫn xài dic của @Nguyễn Duy Tuân xem .... mạnh mới coi qua thấy code đó viết khó quá
mai rảnh coi kỹ lại
 
Upvote 0
Thử 1 code theo hướng dẫn xài dic của @Nguyễn Duy Tuân xem .... mạnh mới coi qua thấy code đó viết khó quá
mai rảnh coi kỹ lại
Nó khong kho dau tu minh chua quen thoi thấy hoi ruon rà
quan trong no phải có
Mã:
type
  TMyData = class
    MaNV: string;
    TenNV: string;
    Tuoi: Integer;
  end;
số ra số, text ra text, rồi mai mốt còn đổ dữ liệu lên máy cái List nữa, đỗ dữ liệu xong chỉnh sửa cho đẹp nữa, hơi bị vui ;);););););););)
 
Upvote 0
Nó khong kho dau tu minh chua quen thoi thấy hoi ruon rà
quan trong no phải có
Mã:
type
  TMyData = class
    MaNV: string;
    TenNV: string;
    Tuoi: Integer;
  end;
số ra số, text ra text, rồi mai mốt còn đổ dữ liệu lên máy cái List nữa, đỗ dữ liệu xong chỉnh sửa cho đẹp nữa, hơi bị vui ;);););););););)
Mạnh đang nghiền ngẫm lại code ....
Mã:
dic: TDictionary<string, TMyData>;
Chưa quen cách khai báo và xài kiểu đó coi thấy Rối :p:D:rolleyes:
 
Lần chỉnh sửa cuối:
Upvote 0
Mạnh đang nghiền ngẫm lại code ....
Mã:
dic: TDictionary<string, TMyData>;
Chưa quen cách khai báo và xài kiểu đó coi thấy Rối :p:D:rolleyes:

Làm Delphi hay .NET đều phải học cách tiếp cận mới, cách tổ chức đối tượng/class mới. VBA vẫn tốt nhưng cách giải quyết vấn đề khác. Delphi hay .NET khác nên cần thay đổi theo.
 
Upvote 0
Làm Delphi hay .NET đều phải học cách tiếp cận mới, cách tổ chức đối tượng/class mới. VBA vẫn tốt nhưng cách giải quyết vấn đề khác. Delphi hay .NET khác nên cần thay đổi theo.
NGày trước khi chuyển qua VB6 cũng vậy bước qua cái ngưỡng khai báo 1 cái là Viết code Vèo vèo
này chuyển qua Delphi cũng gặp y trang vậy ... nhưng Delphi khó hơn nhiều lần ... may có các bạn chì cho đang từng bước Tiếp cận Delphi dần dần

Rồi từng bước từng bước dưới sự chỉ dẫn của các Bạn Mạnh sẻ học Tốt :D:p quan trọng nhất trong code là có người khai đường mở lối cho đi

Tăng cho Những Bạn nào có ý đinh học Delphi Code ADO nè .... Viết theo phong cách sau nó rất gần gủi với VBA ta tiếp cận Delphi Nhanh hơn
Khi nào ta thành thạo Delphi rồi ta chuyển qua Viết Theo Phong cách @Nguyễn Duy Tuân chỉ dẫn là tốt nhất ...
Mã:
Function CopyDataRange(ExcelPath, sSQL: OleVariant;  Range: OleVariant): Longint; stdcall;
var
    cnn,Rst    : OleVariant;
    SQL    : string;
begin
    cnn := CreateOleObject('ADODB.Connection') ;
        cnn.ConnectionString := 'Provider=Microsoft.ACE.OLEDB.12.0;Data Source=' + ExcelPath +
                                ';Extended Properties="Excel 12.0 Xml;HDR=YES";';
        SQL := 'select * from ['+ sSQL + '$]';
        cnn.open;
        rst := cnn.Execute(SQL);
        Result := Range.CopyFromRecordset(rst); //copy data from recordset to Excel range
        cnn.close
end;
 
Upvote 0
Các Bạn cho Mình hỏi chút
Trên VBA mình viết Hàm có Tùy chọn : Optional
Vậy trên Delphi viết Hàm xài Tùy chon Optional như thế nào .... Mong chỉ dẫn
VD: trên VBA mình Viết Hàm sau: Vậy Trong Delphi Viết Sao

Mã:
Public Function UniMsgbox(Optional Message$, Optional TimeOut = "", Optional Format = "", Optional Msg)
    Rem Cu Phap object.Popup (Message [, TimeOut][, Title] [, Format])
    Dim Title As String
    If Format = "" Then Format = 64     '' Icon Mac dinh la 64 ...Tuy Chon Tham So 1,2,3,4,5,48,64,65,67,68...
    If TimeOut = "" Then TimeOut = 3    '' Thoi gian Thoat Mac dinh la 3 Giay
    Title = "Ph" & ChrW(432) & ChrW(417) & "ng" & " Nam" & " Telecom" & ChrW(174)
    Msg = CreateObject("Wscript.shell").PopUp(Message, TimeOut, Title, Format)
End Function
Xin Cảm Ơn
 
Upvote 0
NGày trước khi chuyển qua VB6 cũng vậy bước qua cái ngưỡng khai báo 1 cái là Viết code Vèo vèo
này chuyển qua Delphi cũng gặp y trang vậy ... nhưng Delphi khó hơn nhiều lần ... may có các bạn chì cho đang từng bước Tiếp cận Delphi dần dần

Rồi từng bước từng bước dưới sự chỉ dẫn của các Bạn Mạnh sẻ học Tốt :D:p quan trọng nhất trong code là có người khai đường mở lối cho đi

Tăng cho Những Bạn nào có ý đinh học Delphi Code ADO nè .... Viết theo phong cách sau nó rất gần gủi với VBA ta tiếp cận Delphi Nhanh hơn
Khi nào ta thành thạo Delphi rồi ta chuyển qua Viết Theo Phong cách @Nguyễn Duy Tuân chỉ dẫn là tốt nhất ...
Mã:
Function CopyDataRange(ExcelPath, sSQL: OleVariant;  Range: OleVariant): Longint; stdcall;
var
    cnn,Rst    : OleVariant;
    SQL    : string;
begin
    cnn := CreateOleObject('ADODB.Connection') ;
        cnn.ConnectionString := 'Provider=Microsoft.ACE.OLEDB.12.0;Data Source=' + ExcelPath +
                                ';Extended Properties="Excel 12.0 Xml;HDR=YES";';
        SQL := 'select * from ['+ sSQL + '$]';
        cnn.open;
        rst := cnn.Execute(SQL);
        Result := Range.CopyFromRecordset(rst); //copy data from recordset to Excel range
        cnn.close
end;
[/QUCai nay minh chay bi loi
invalid variant operation
Bài đã được tự động gộp:

Các Bạn cho Mình hỏi chút
Trên VBA mình viết Hàm có Tùy chọn : Optional
Vậy trên Delphi viết Hàm xài Tùy chon Optional như thế nào .... Mong chỉ dẫn
VD: trên VBA mình Viết Hàm sau: Vậy Trong Delphi Viết Sao

Mã:
Public Function UniMsgbox(Optional Message$, Optional TimeOut = "", Optional Format = "", Optional Msg)
    Rem Cu Phap object.Popup (Message [, TimeOut][, Title] [, Format])
    Dim Title As String
    If Format = "" Then Format = 64     '' Icon Mac dinh la 64 ...Tuy Chon Tham So 1,2,3,4,5,48,64,65,67,68...
    If TimeOut = "" Then TimeOut = 3    '' Thoi gian Thoat Mac dinh la 3 Giay
    Title = "Ph" & ChrW(432) & ChrW(417) & "ng" & " Nam" & " Telecom" & ChrW(174)
    Msg = CreateObject("Wscript.shell").PopUp(Message, TimeOut, Title, Format)
End Function
Xin Cảm Ơn
;CONST ForeColor : TColor=clBlack
 
Upvote 0
Thử vầy Xem sao Nhé ... bỏ dòng này cnn.close

Mã:
Declare Function CopyDataRange Lib "VBLibrary.dll" _
                    (ByVal ExcelPath As Variant, _
                     ByVal sSQL As Variant, _
                     ByVal Target As Variant) As Long

Rem ==========
Sub MainCopyDataRange()
    Dim FilePath As Variant, DataRange  As Variant
    DataRange = "Data_Nhap" ''Ten SheetName (ko Phai SheetCodeName)
    Cells.ClearContents
    FilePath = ThisWorkbook.Path & "\Data.xlsb"
    Call CopyDataRange(FilePath, DataRange, Range("A2"))
End Sub
 
Upvote 0
Thử vầy Xem sao Nhé ... bỏ dòng này cnn.close

Mã:
Declare Function CopyDataRange Lib "VBLibrary.dll" _
                    (ByVal ExcelPath As Variant, _
                     ByVal sSQL As Variant, _
                     ByVal Target As Variant) As Long

Rem ==========
Sub MainCopyDataRange()
    Dim FilePath As Variant, DataRange  As Variant
    DataRange = "Data_Nhap" ''Ten SheetName (ko Phai SheetCodeName)
    Cells.ClearContents
    FilePath = ThisWorkbook.Path & "\Data.xlsb"
    Call CopyDataRange(FilePath, DataRange, Range("A2"))
End Sub
Mã:
while not rst.EOF do
dụng while not rst.EOF đó thì không gì mà dùng Range.CopyFromRecordset(rst); là báo lỗi
 
Upvote 0
Mã:
while not rst.EOF do
dụng while not rst.EOF đó thì không gì mà dùng Range.CopyFromRecordset(rst); là báo lỗi
Thấy máy mạnh chạy tốt ... chưa hiểu lỗi tại sao lắm nếu vậy thêm dòng sau đi cho nó an toàn
Mã:
while not rst.EOF
 
Upvote 0
Nếu ADO thì Mạnh hay xài dòng sau
Mã:
If Not Rst.EOF Then begin
 
Upvote 0
Cái này thấy có 3 người coi bộ cũng vui, còn mấy bửa nay cái vụ VSTO của tôi mày mò có một mình cũng buồn, nhưng càng mày mò thì cách thấy nó cũng hay hay. Nhưng sao mò một mình lâu quá, có khi một vấn đề mà mất mấy hôm luôn. :eek:
 
Upvote 0
Cái này thấy có 3 người coi bộ cũng vui, còn mấy bửa nay cái vụ VSTO của tôi mày mò có một mình cũng buồn, nhưng càng mày mò thì cách thấy nó cũng hay hay. Nhưng sao mò một mình lâu quá, có khi một vấn đề mà mất mấy hôm luôn. :eek:
-0-0-0-===\. qua đây đi cho xôm tụ vui vẻ .... Mạnh Học thấy ok đó ... Bước qua cái ngưỡng khai báo và cú pháp là Tạm ok
Còn thuật toán linh tinh trong đó viết nhiều kẹt tới đâu hỏi tới đó khắc tự nó khá lên à ??!!
 
Lần chỉnh sửa cuối:
Upvote 0
VSTO cũng na ná như Delphi, mà cái Soure của nó nặng quá
Bài đã được tự động gộp:

Cái này thấy có 3 người coi bộ cũng vui, còn mấy bửa nay cái vụ VSTO của tôi mày mò có một mình cũng buồn, nhưng càng mày mò thì cách thấy nó cũng hay hay. Nhưng sao mò một mình lâu quá, có khi một vấn đề mà mất mấy hôm luôn. :eek:
Nói tới cái vụ mò mới nhớ, đợt trước mình bỏ ra cả tháng tìm hiểu cái vụ Hook lấy text của Cell mà có ra đâu rồi cũng không biết hỏi ai bắt đầu từ đâu :oops::oops::oops:
 
Lần chỉnh sửa cuối:
Upvote 0
Tặng cho bạn nào có ý đinh nhập Môn Delphi sử dụng ADO lấy dữ liệu vào Mảng 2dArray

1/ Mục đích mong muốn các bạn tiếp cận Delphi gần gủi hơn với VBA ...
2/ Có Nhiều Bạn tham gia học .... sẻ có nhiều câu hỏi phát sinh hay ==> sẻ có nhiều cái hay mà học tương tác qua lại lẫn nhau ??!!!!
3/ Nếu 2 mục trên phát triển tốt thì từng bước Mạnh sẻ học Delphi tốt hơn rất nhiều

4/ Vì mấy mục trên Nên Mạnh viết được code nào Úp cho các bạn tham khảo và điều chỉnh bổ sung thêm cho hoàn thiện
....
5/ Phải nói thật là 2 thầy chỉ 1 trò học nhanh thật ... Xin cảm ơn -0-0-0-
Hàm trong File *.dll Delphi
Mã:
Function GetDataRangeArray(ExcelPath, sSQL: OleVariant): OleVariant; stdcall;
var
  cnn,Rst       : OleVariant;
  SQL,Strcon    : string;
  x         : OleVariant;
begin
  cnn := CreateOleObject('ADODB.Connection') ;
  Rst := CreateOleObject('ADODB.Recordset');
  Strcon := 'Provider=Microsoft.ACE.OLEDB.12.0;Data Source=' + ExcelPath +
            ';Extended Properties="Excel 12.0 Xml;HDR=YES";';
  cnn.open(Strcon);
  SQL := 'select * from ['+ sSQL + '$]' ;
  Rst.Open(SQL, cnn, 3, 1) ;
  x := rst.RecordCount;
  If Not Rst.EOF Then begin
     ShowMessage(x);
     Result := rst.GetRows();
   end;
end;
Khai báo sử dụng trên VBA
Mã:
Declare Function GetDataRangeArray Lib "VBLibrary.dll" _
                    (ByVal ExcelPath As Variant, _
                     ByVal sSQL As Variant) As Variant
                  
Sub Main_GetDataRangeArray()
    Dim FilePath As Variant, DataRange  As Variant
    Dim Arr As Variant, dArr(), i As Long, j As Long
    DataRange = "Data_Nhap"             ''Ten SheetName
  
    FilePath = ThisWorkbook.Path & "\Data.xlsb"
    Arr = GetDataRangeArray(FilePath, DataRange)
  
    ReDim dArr(1 To UBound(Arr, 2) + 1, 1 To UBound(Arr, 1) + 1)  ''Chuyen mang
    For i = 0 To UBound(Arr, 2)                                   ''Mang ADO lay len Bat dau tu o
        For j = 0 To UBound(Arr, 1)
            dArr(i + 1, j + 1) = Arr(j, i)                        ''Mang ADO lay len Bat dau tu o nen Phai + them 1
        Next
    Next
  
    Cells.ClearContents
    Range("A4").Resize(UBound(dArr, 1), UBound(dArr, 2)) = dArr
End Sub
 
Upvote 0
Tặng cho bạn nào có ý đinh nhập Môn Delphi sử dụng ADO lấy dữ liệu vào Mảng 2dArray

1/ Mục đích mong muốn các bạn tiếp cận Delphi gần gủi hơn với VBA ...
2/ Có Nhiều Bạn tham gia học .... sẻ có nhiều câu hỏi phát sinh hay ==> sẻ có nhiều cái hay mà học tương tác qua lại lẫn nhau ??!!!!
3/ Nếu 2 mục trên phát triển tốt thì từng bước Mạnh sẻ học Delphi tốt hơn rất nhiều

4/ Vì mấy mục trên Nên Mạnh viết được code nào Úp cho các bạn tham khảo và điều chỉnh bổ sung thêm cho hoàn thiện
....
5/ Phải nói thật là 2 thầy chỉ 1 trò học nhanh thật ... Xin cảm ơn -0-0-0-
Hàm trong File *.dll Delphi
Mã:
Function GetDataRangeArray(ExcelPath, sSQL: OleVariant): OleVariant; stdcall;
var
  cnn,Rst       : OleVariant;
  SQL,Strcon    : string;
[CODE]try
finally
end;

try
except
end;
x : OleVariant;
begin
cnn := CreateOleObject('ADODB.Connection') ;
Rst := CreateOleObject('ADODB.Recordset');
Strcon := 'Provider=Microsoft.ACE.OLEDB.12.0;Data Source=' + ExcelPath +
';Extended Properties="Excel 12.0 Xml;HDR=YES";';
cnn.open(Strcon);
SQL := 'select * from ['+ sSQL + '$]' ;
Rst.Open(SQL, cnn, 3, 1) ;
x := rst.RecordCount;
If Not Rst.EOF Then begin
ShowMessage(x);
Result := rst.GetRows();
end;
end;[/CODE]
Khai báo sử dụng trên VBA
Mã:
Declare Function GetDataRangeArray Lib "VBLibrary.dll" _
                    (ByVal ExcelPath As Variant, _
                     ByVal sSQL As Variant) As Variant
              
Sub Main_GetDataRangeArray()
    Dim FilePath As Variant, DataRange  As Variant
    Dim Arr As Variant, dArr(), i As Long, j As Long
    DataRange = "Data_Nhap"             ''Ten SheetName

    FilePath = ThisWorkbook.Path & "\Data.xlsb"
    Arr = GetDataRangeArray(FilePath, DataRange)

    ReDim dArr(1 To UBound(Arr, 2) + 1, 1 To UBound(Arr, 1) + 1)  ''Chuyen mang
    For i = 0 To UBound(Arr, 2)                                   ''Mang ADO lay len Bat dau tu o
        For j = 0 To UBound(Arr, 1)
            dArr(i + 1, j + 1) = Arr(j, i)                        ''Mang ADO lay len Bat dau tu o nen Phai + them 1
        Next
    Next

    Cells.ClearContents
    Range("A4").Resize(UBound(dArr, 1), UBound(dArr, 2)) = dArr
End Sub
mạnh phải kèm thêm cái bẫy lỗi Try giống của anh Tuân nữa
Try
finally
End;

Try
except
End;

Tùy theo ý đồ mà mình sử dụng cho phù hợp
 
Upvote 0
Các Bạn cho Mình hỏi chút
Trên VBA mình viết Hàm có Tùy chọn : Optional
Vậy trên Delphi viết Hàm xài Tùy chon Optional như thế nào .... Mong chỉ dẫn
VD: trên VBA mình Viết Hàm sau: Vậy Trong Delphi Viết Sao

Mã:
Public Function UniMsgbox(Optional Message$, Optional TimeOut = "", Optional Format = "", Optional Msg)
    Rem Cu Phap object.Popup (Message [, TimeOut][, Title] [, Format])
    Dim Title As String
    If Format = "" Then Format = 64     '' Icon Mac dinh la 64 ...Tuy Chon Tham So 1,2,3,4,5,48,64,65,67,68...
    If TimeOut = "" Then TimeOut = 3    '' Thoi gian Thoat Mac dinh la 3 Giay
    Title = "Ph" & ChrW(432) & ChrW(417) & "ng" & " Nam" & " Telecom" & ChrW(174)
    Msg = CreateObject("Wscript.shell").PopUp(Message, TimeOut, Title, Format)
End Function
Xin Cảm Ơn
@thuyyeu99 chỉ cho Mạnh học bài này đi he
 
Upvote 0
@thuyyeu99 chỉ cho Mạnh học bài này đi he

Cách khai báo tham số ngầm định trong hàm haowcj thủ tục:
+ Trong VBA: Optional Byval Bien As Boolean = True
+ Trong Delphi: const Bien: Boolean = True

Khi khai báo hàm API trong VBA thì khai báo Optional nếu bạn cần, dù trong hàm Delphi không khai báo tùy chọn.
 
Upvote 0
Mạnh viết 1 Sub mảng lọc ngày/thang/nam To ngay/thang/nam ... Lọc mảng 1dArray

1/ Code viết chạy tốt ... tốc độ rất nhanh

2/ Úp bài nhờ các Bạn coi dùm cách khai báo và truyền 1 tham số Date trong Delphi như vậy là đúng chưa ?! ...
cấu trúc viết 1 Sub truyền tham số như vậy là ok chưa vv...

3/ Code trong Delpohi *.dll
Mã:
procedure FilterDate1dArray(sArr: OleVariant; Fdate, Edate: TDateTime;
                            ColDate: Longint; Range: OleVariant); stdcall;
var
    Arr     : OleVariant;
    i,j,k     : longint;
    lcols,lRows : longint;
begin
    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);
    for i := 1 to lRows do begin
       If sArr[i, ColDate] >= Fdate Then  begin
         If sArr[i, ColDate] <= Edate Then begin
            k := k + 1;
            For j := 1 To lcols do begin
               Arr[k, j] := sArr[i, j];
            End;
         End;
       End;
    End;
    if k <> 0 then begin
       Range.Resize[k, lcols]:=Arr;  //gan ket Qua Len Range Theo Mang Arr
    end;
End;
4/ Khai báo sử dụng Hàm trên VBA
Mã:
Declare Sub FilterDate1dArray Lib "VBLibrary.dll" (ByVal sArr As Variant, _
                                         ByVal Fdate As Date, ByVal Edate As Date, _
                                         ByVal ColDate As Long, ByVal Target As Variant)

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim Arr As Variant
    Dim Fdate As Date, Edate As Date
    Fdate = [I1].Value ''Ngay bat dau
    Edate = [I2].Value ''ngay ket thuc
 
    Arr = Sheet1.Range("A2:I65536").Value
 
    Application.ScreenUpdating = False
    Application.EnableEvents = False
        If Not Intersect(Target, [I1:I2]) Is Nothing Then
            If Not IsNumeric(Target) And Not IsDate(Target) Then
                Target = ""
                Target.Select
            Else
                Range("A3:I1000").ClearContents
                Call FilterDate1dArray(Arr, Fdate, Edate, 9, [A3]) ''Tham số 9 là cột ngay/thang/nam
                Target.Select
            End If
        End If
    Application.EnableEvents = True
    Application.ScreenUpdating = True
End Sub
Mong các bạn coi và chỉ dùm ... xin cảm ơn
 
Lần chỉnh sửa cuối:
Upvote 0
Thấy hơi hay hay nên tính mò đầu vào. Các bạn cho mình hỏi là nên cài bản nào để 'mò đầu' vào và nếu có link down thì cho mình luôn nhé.
Xin cảm ơn !
 
Upvote 0
Thấy hơi hay hay nên tính mò đầu vào. Các bạn cho mình hỏi là nên cài bản nào để 'mò đầu' vào và nếu có link down thì cho mình luôn nhé.
Xin cảm ơn !
Theo mình nghĩ bạn nên tải Delphi7 vì bản này rất nhẹ có trên 200M sau khi cài đặt ( có điều bản này ko hổ trợ Unicode và Build đa nền tảng ...)
Còn Delphi thì rất nhiều bản hiện mình đang xài Delphi XE6
sau này rành rồi thì cả xài bản mới nhất he
Tìm với Google nhé
https://www.google.com.vn/search?q=...69i57j69i65.3010j0j7&sourceid=chrome&ie=UTF-8
 
Lần chỉnh sửa cuối:
Upvote 0
Cái này thấy có 3 người coi bộ cũng vui, còn mấy bửa nay cái vụ VSTO của tôi mày mò có một mình cũng buồn, nhưng càng mày mò thì cách thấy nó cũng hay hay. Nhưng sao mò một mình lâu quá, có khi một vấn đề mà mất mấy hôm luôn. :eek:
Mình đang nghiên cứu VSTO thấy cũng hay và đang tiến bộ về nó, nhưng do không có nhiều thời gian nên vẫn đang bò từ từ. Mà bạn đã từng dùng VSTO sẳn cho hỏi luôn (đừng cho là lạc chủ đề nhé) sao mình thao tác thay đổi giá trị trong ô của Excel nó hơi chậm hơn so với dùng code VBA, mặc dù giải thuật như nhau. Ví dụ mình muốn thay đổi Font chữ trong vùng đang chọn (Khoảng 1000 dòng, 20 cột), thì dùng code VBA sẽ nhanh hơn khoảng 1 giây so với code VSTO. Còn nếu dùng mảng lưu giá trị và gán ngược vào ô trong Excel thì như nhau (Nhưng cách này lại không phù hợp vì vùng chọn có thể các ô không liên tục). Bạn từng dùng và có kinh nghiệm chia sẻ cho mình với (Có thể chỉ hướng không cần code mẫu cũng được).
 
Upvote 0
Mình đang nghiên cứu VSTO thấy cũng hay và đang tiến bộ về nó, nhưng do không có nhiều thời gian nên vẫn đang bò từ từ. Mà bạn đã từng dùng VSTO sẳn cho hỏi luôn (đừng cho là lạc chủ đề nhé) sao mình thao tác thay đổi giá trị trong ô của Excel nó hơi chậm hơn so với dùng code VBA, mặc dù giải thuật như nhau. Ví dụ mình muốn thay đổi Font chữ trong vùng đang chọn (Khoảng 1000 dòng, 20 cột), thì dùng code VBA sẽ nhanh hơn khoảng 1 giây so với code VSTO. Còn nếu dùng mảng lưu giá trị và gán ngược vào ô trong Excel thì như nhau (Nhưng cách này lại không phù hợp vì vùng chọn có thể các ô không liên tục). Bạn từng dùng và có kinh nghiệm chia sẻ cho mình với (Có thể chỉ hướng không cần code mẫu cũng được).
Mạnh bỏ 2 năm nay rồi ko cài nên ko thử lại nên ko biết
Chỉ biết là hồi đó viết cái Add-ins *.xll thấy chạy tốt tuy nhiên viết nhiều code vô đó khi nó load chậm quá và xài lại các hàm trong đó rất bất tiện
nếu ai đó xài bản thân file của người ta đầy hàm linh tinh mở lên đã chậm ròi lại cỏng thêm cái add-ins kia nữa mới thấy cảnh bực bội .... vì vậy mạnh bỏ lâu rồi ...
Có lẻ 1 mình 1 ngựa và 1 con đường chạy đi he

Mạnh nói nhỏ thui he hỏi HLMT ý .... hay món đó lắm he ... hôm rồi thấy úp lên Facebook thử nghiệm hay lắm he
 
Upvote 0
@thuyyeu99 chỉ cho Mạnh học bài này đi he
Xin lỗi giờ mới có Thời gian phản hồi lại bạn
Mã:
function UniMsgbox(const Message1: String; const TimeOut: integer=64; const Format: integer=3): OleVariant;
var
    Title: String;
    Msg: OleVariant;
begin
    Title := 'Phng'+' Nam'+' Telecom';
   Msg:= CreateOleObject('Wscript.shell');
   Result := Msg.PopUp(Message1, TimeOut, Title, Format);
end;
procedure TForm1.Button27Click(Sender: TObject);
begin
UniMsgbox('Nguyễn Thị Thanh Thủy',3,1) ;
end;
 
Upvote 0
Mạnh viết 1 Sub mảng lọc ngày/thang/nam To ngay/thang/nam ... Lọc mảng 1dArray

1/ Code viết chạy tốt ... tốc độ rất nhanh

2/ Úp bài nhờ các Bạn coi dùm cách khai báo và truyền 1 tham số Date trong Delphi như vậy là đúng chưa ?! ...
cấu trúc viết 1 Sub truyền tham số như vậy là ok chưa vv...

3/ Code trong Delpohi *.dll
Mã:
procedure FilterDate1dArray(sArr: OleVariant; Fdate, Edate: TDateTime;
                            ColDate: Longint; Range: OleVariant); stdcall;
var
    Arr     : OleVariant;
    i,j,k     : longint;
    lcols,lRows : longint;
begin
    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);
    for i := 1 to lRows do begin
       If sArr[i, ColDate] >= Fdate Then  begin
         If sArr[i, ColDate] <= Edate Then begin
            k := k + 1;
            For j := 1 To lcols do begin
               Arr[k, j] := sArr[i, j];
            End;
         End;
       End;
    End;
    if k <> 0 then begin
       Range.Resize[k, lcols]:=Arr;  //gan ket Qua Len Range Theo Mang Arr
    end;
End;
4/ Khai báo sử dụng Hàm trên VBA
Mã:
Declare Sub FilterDate1dArray Lib "VBLibrary.dll" (ByVal sArr As Variant, _
                                         ByVal Fdate As Date, ByVal Edate As Date, _
                                         ByVal ColDate As Long, ByVal Target As Variant)

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim Arr As Variant
    Dim Fdate As Date, Edate As Date
    Fdate = [I1].Value ''Ngay bat dau
    Edate = [I2].Value ''ngay ket thuc

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

    Application.ScreenUpdating = False
    Application.EnableEvents = False
        If Not Intersect(Target, [I1:I2]) Is Nothing Then
            If Not IsNumeric(Target) And Not IsDate(Target) Then
                Target = ""
                Target.Select
            Else
                Range("A3:I1000").ClearContents
                Call FilterDate1dArray(Arr, Fdate, Edate, 9, [A3]) ''Tham số 9 là cột ngay/thang/nam
                Target.Select
            End If
        End If
    Application.EnableEvents = True
    Application.ScreenUpdating = True
End Sub
Mong các bạn coi và chỉ dùm ... xin cảm ơn
bạn cho mình cái dữ liệu trên Excel đi
 
Upvote 0
Xin lỗi giờ mới có Thời gian phản hồi lại bạn
Mã:
function UniMsgbox(const Message1: String; const TimeOut: integer=64; const Format: integer=3): OleVariant;
var
    Title: String;
    Msg: OleVariant;
begin
    Title := 'Phng'+' Nam'+' Telecom';
   Msg:= CreateOleObject('Wscript.shell');
   Result := Msg.PopUp(Message1, TimeOut, Title, Format);
end;
procedure TForm1.Button27Click(Sender: TObject);
begin
UniMsgbox('Nguyễn Thị Thanh Thủy',3,1) ;
end;
Chạy tốt đó mà sao truyền tham số từ Excel vào nó lỗi Font ??? chưa hiểu lắmCapture.PNG
Bài đã được tự động gộp:

bạn cho mình cái dữ liệu trên Excel đi
Bạn Coi lại cột ngay/thang/nam nhé nếu chưa chuẩn Format lai Date
 

File đính kèm

Upvote 0
Xin lỗi giờ mới có Thời gian phản hồi lại bạn
Mã:
function UniMsgbox(const Message1: String; const TimeOut: integer=64; const Format: integer=3): OleVariant;
var
    Title: String;
    Msg: OleVariant;
begin
    Title := 'Phng'+' Nam'+' Telecom';
   Msg:= CreateOleObject('Wscript.shell');
   Result := Msg.PopUp(Message1, TimeOut, Title, Format);
end;
procedure TForm1.Button27Click(Sender: TObject);
begin
UniMsgbox('Nguyễn Thị Thanh Thủy',3,1) ;
end;
Arr no la String
mạnh chuyển Fdate, Edate: String;
Còn hàm chuyển đổi
(DateTimeToStr((Edate)));
(StrToDateTime((Edate)));
 
Upvote 0
Arr no la String
mạnh chuyển Fdate, Edate: String;
Còn hàm chuyển đổi
(DateTimeToStr((Edate)));
(StrToDateTime((Edate)));
2 dòng sau sửa lại sao mạnh sửa khi Build nó báo lỗi
Mã:
If sArr[i, ColDate] >= Fdate Then  begin
         If sArr[i, ColDate] <= Edate Then begin
 
Upvote 0
2 dòng sau sửa lại sao mạnh sửa khi Build nó báo lỗi
Mã:
If sArr[i, ColDate] >= Fdate Then  begin
         If sArr[i, ColDate] <= Edate Then begin
mình dâu có sữa gì đâu chỉ đổi date thành String phia khai báo rồi chạy
FilterDate1dArray(E.Range['A2:I65536'].Value, E.Range['I1'].Value, E.Range['I2'].Value, 9, E.Range['K3']) //''Tham số 9 là cột ngay/thang/nam
Mã:
procedure FilterDate1dArray(sArr: OleVariant; Fdate, Edate: String;
                            ColDate: Longint; Range: OleVariant); stdcall;
var
    Arr     : OleVariant;
    i,j,k     : longint;
    lcols,lRows : longint;
begin
    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);
    for i := 1 to lRows do begin
       If (sArr[i, ColDate]) >= (Fdate) Then  begin
         If (sArr[i, ColDate]) <= (Edate) Then begin
            k := k + 1;
            For j := 1 To lcols do begin
               Arr[k, j] := sArr[i, j];
            End;
         End;
       End;
    End;
    if k <> 0 then begin
       Range.Resize[k, lcols]:=Arr;  //gan ket Qua Len Range Theo Mang Arr
    end;
End;

Chach mạnh cho mình cái File của mạnh Test thửUntitled2.jpg
 
Lần chỉnh sửa cuối:
Upvote 0
mình dâu có sữa gì đâu chỉ đổi date thành String phia khai báo rồi chạy
FilterDate1dArray(E.Range['A2:I65536'].Value, E.Range['I1'].Value, E.Range['I2'].Value, 9, E.Range['K3']) //''Tham số 9 là cột ngay/thang/nam
Mã:
procedure FilterDate1dArray(sArr: OleVariant; Fdate, Edate: String;
                            ColDate: Longint; Range: OleVariant); stdcall;
var
    Arr     : OleVariant;
    i,j,k     : longint;
    lcols,lRows : longint;
begin
    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);
    for i := 1 to lRows do begin
       If (sArr[i, ColDate]) >= (Fdate) Then  begin
         If (sArr[i, ColDate]) <= (Edate) Then begin
            k := k + 1;
            For j := 1 To lcols do begin
               Arr[k, j] := sArr[i, j];
            End;
         End;
       End;
    End;
    if k <> 0 then begin
       Range.Resize[k, lcols]:=Arr;  //gan ket Qua Len Range Theo Mang Arr
    end;
End;

Chach mạnh cho mình cái File của mạnh Test thửView attachment 204853
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
 
Lần chỉnh sửa cuối:
Upvote 0

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
của mình mỗi lần chạy phải đăng ký
Để mỗi lần chạy ko phải đăng ký ta làm như sau:

1/ Copy File *.dll vô Windows\System32\*.dll ===> Windowsx32

2/ Copy File *.dll vô Windows\SysWOW64 \*.dll ===> Windowsx64

3/ Nêu ko làm theo mục 1 & 2 thì ta làm như sau cho tiện gọn khi ta test code sẻ rất nhanh khỏi phải mất công copy sau mỗi lần Build File *.dll

- Tao 1 File Excel copy vô thư mục (Build Delphi) ... TenFolder\Win32\Debug\*.dll ===> Officex32
- Tao 1 File Excel copy vô thư mục (Build Delphi) ... TenFolder\Win64\Debug\*.dll ===> Officex64

4/ Xong Copy code sau vào 1 Module Excel .... làm như vậy mỗi lần Build xong muốn test code thì khỏi mất công làm như mục 1 & 2 nữa
Ta chỉ việc mở File Excel đó lên chạy code thui còn mấy hàm API kia nó làm nhiệm vụ load *dll hàm trong đó cho rồi

5/ Nếu ta Build tiếp thì nên thoát File Excel đi cả build vì khi đó Excel vẫn còn kết nối với *.dll .... Nếu để vậy vẫn ok nhưng khi Build ta buộc phải chọn OK của Delphi thì nó mới kết thúc

6/ Lưu ý : Officex32 chỉ chạy file *.dll trong TenFolder\Win32\Debug\*.dll ===> Officex32 ( và ngược lại )
còn máy Windowsx64 hay Windowsx32 gì thì kệ bà nó he ko quan tâm -0-0-0-===\.

Mã:
Private Declare Function FreeLibrary Lib "kernel32" _
                        (ByVal hLibModule As Long) As Long
Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" _
                        (ByVal lpLibFileName$) As Long
Dim hModule As Long
Rem 1/ Cach viet nay Ap dung Cho File *.DLL cung Folder lam don Gian khai bao su dung Ham dai dong
Rem 2/ Ap dung Cho WindowsX32: Copy Vao Windows\System32\VBLibrary.dll
Rem 3/ Ap dung Cho WindowsX64: Copy Vao Windows\SysWOW64\VBLibrary.dll
Rem 4/ Neu thuc hien Muc 2 Or 3 thi xoa het Code trong Module Nay
Rem ==========
Private Function LoadDLL() As Long
    LoadDLL = LoadLibrary(ThisWorkbook.Path & "\VBLibrary.dll")
End Function
Rem ==========
Private Sub FreeDLL(hModule As Long)
    Do Until FreeLibrary(hModule) = 0
    Loop
End Sub
Rem ==========
Public Sub AuTo_Open()
    Rem Load the DLL into memory
    hModule = LoadDLL()
End Sub
Rem ==========
Public Sub Auto_Close()
    Rem Unload the DLL from memory
    Call FreeDLL(hModule)
End Sub
Rem ==========
 
Upvote 0
Các bạn đang bị nhầm lẫn việc đăng ký hoặc không đăng ký DLL. Có 2 loại thư viện:
1. Standard DLL: là loại thư viện chỉ cần khai báo hàm xuất bởi các thư viện đó trong các môi trường lập trình khác là chạy được. Với việc khai báo Declare thì chỉ chạy các function, sub mà thôi, chứ không khởi tạo được Object/ Class do người lâp trình tạo ra. Video bài đầu tiên là loại DLL này.

2. ActiveX DLL/OCX: đây là loại thư viện vừa chứa các hàm tĩnh/static của Standard DLL vừa cho phép chứa các Object/Class của người lập trình tạo ra. Muốn môi trường lập trình khác sử dụng được các Class trong DLL/OCX này thì bắt buộc phải khai báo các lớp Class - Interface tới Registry của Windows, vì thế với loại thư viện và mục đích sử dụng Class nên ta phải đăng ký tới Windows - Registry bởi lệnh REGSVR32...

Trong video bài đầu tiên tôi hướng dẫn, đó là cách làm Starndard DLL, giống với cách Microsoft tạo ra các thư viện cung cấp các hàm API: user32.dll,.... Đây có thể nói là niềm mơ ước của người lập trình VB6, VBA đấy, vì đây là thư viện chuẩn của Windows, mang đi bất kỳ máy tính nào cũng chạy, không cần .NET gì cả, hỗ trợ cả 32, 64 bit, unicode, tốc độ thì nhanh khủng khiếp. XLL bản chất là Standard DLL nhé!
 
Upvote 0
Upvote 0
Bên Delphi dùng tham số OleVariant, VBA, VB6 là Variant thay cho String là được nhé.
Mình mới thử xong nó đơ luôn ... Hàm như sau nhờ Bạn sửa dùm
Mã:
function UniMsgbox(const Message1: String; const TimeOut: integer=64;
           const Format: integer=3): OleVariant; stdcall;
var
    Title    : String;
    Msg        : OleVariant;
begin
    Title := 'Phương'+' Nam'+' Telecom';
    Msg:= CreateOleObject('Wscript.shell');
    Result := Msg.PopUp(Message1, TimeOut, Title, Format);
end;
 
Lần chỉnh sửa cuối:
Upvote 0
Mình mới thử xong nó đơ luôn ... Hàm như sau nhờ Bạn sửa dùm
Mã:
function UniMsgbox(const Message1: OleVariant; const TimeOut: integer=64;
           const Format: integer=3): OleVariant; stdcall;
var
    Title    : String;
    Msg        : OleVariant;
begin
    Title := 'Phương'+' Nam'+' Telecom';
    Msg:= CreateOleObject('Wscript.shell');
    Result := Msg.PopUp(Message1, TimeOut, Title, Format);
end;
Cái này mình thua. File.exe, Active.Dll thì chạy đúng mà sao Standard.DLL nó không thể Get Unicode từ Excel bó tay mò chưa ra chắc phải qua bước convert qua char quá
 
Upvote 0
Mình mới thử xong nó đơ luôn ... Hàm như sau nhờ Bạn sửa dùm
Mã:
function UniMsgbox(const Message1: OleVariant; const TimeOut: integer=64;
           const Format: integer=3): OleVariant; stdcall;
var
    Title    : String;
    Msg        : OleVariant;
begin
    Title := 'Phương'+' Nam'+' Telecom';
    Msg:= CreateOleObject('Wscript.shell');
    Result := Msg.PopUp(Message1, TimeOut, Title, Format);
end;

Bạn thử bỏ "Const" đi ở những khai báo kiểu OleVariant
 
Upvote 0
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

Bài viết mới nhất

Back
Top Bottom