Một câu cụt lủn như thế thì chịu không biết ý bạn thế nào.
Nếu chỉ 1 dòng cụt lủn thì khó có thể đoán ý bạn. Cũng như "bài trước" bạn chỉ tung lên 1 dòng thì không ai đoán được nguyên nhân lỗi đâu. Mà đoán được thì hơi khó. Chỉ khi tung lên toàn bộ code từ A đến Z thì may ra có người chỉ ra được nguyên nhân sảy ra lỗi.
Thế nếu trong trường hợp 1 bạn dùng xlToLeft có được không? Thực ra End chỉ đòi hỏi, chỉ chờ đợi 1 con số. Chỉ phải nhập đúng con số thôi chứ nó có phân biệt con số đó lấy từ kho của công ty A hay từ vườn của bà B đâu. Cứ đúng con số là được.
Kiểu ShortString luôn được phân 256 bai cho dù tùy từng thời điểm mà độ lớn của chuỗi có thể ngắn hơn rất nhiều. Biến ShortString luôn được phân cho 256 bai, trong đó bai đầu tiên được dùng để nhớ độ dài hiện hành của chuỗi, và chuỗi chỉ có thể dài nhất là 255 ký tự.
Biến d và f được phân cho 31 và 17. Dễ hiểu.
Tại sao chỉ có 4 bai được phân cho biến a? Thực ra một chuỗi bất kỳ thì không thể biết nó sẽ có độ lớn bao nhiêu để phân bộ nhớ cho nó. Vì thế "người ta" sẽ làm như sau:
- ở đâu đó trong bộ nhớ, vd. ở địa chỉ abc trong bộ nhớ, sẽ được "đặt đơn" 4 bai cho biến a.
- khi chuỗi a được thiết lập giá trị cụ thể thì ở đâu đó trong bộ nhớ, vd. ở địa chỉ xyz trong bộ nhớ, Manager Memory của Delphi sẽ phân cho một vùng đủ lớn để ghi chuỗi hiện hành.
- địa chỉ trong bộ nhớ của chuỗi hiện hành, tức xyz, được ghi vào 4 bai ở địa chỉ abc.
Nói nôm na thì a chỉ có 4 bai và ghi nhớ địa chỉ hiện hành của chuỗi, còn bản thân chuỗi nằm ở địa chỉ khác.
Nếu a thay đổi giá trị chuỗi nhiều lần thì địa chỉ xyz có thể thay đổi (chuỗi a thay đổi địa chỉ tạm trú) và địa chỉ mới (chỉ là con số) sẽ được ghi vào 4 bai ở địa chỉ abc trong bộ nhớ.
String trong VBA tương tự.
Dim a As String
thì thực ra a chỉ được phân cho 4 bai, giả sử 4 bai được phân cho a nằm ở địa chỉ abc trong bộ nhớ. Chuỗi sẽ được ghi ở địa chỉ xyz trong bộ nhớ, và giá trị xyz sẽ được ghi vào 4 bai nằm ở địa chỉ abc. Nói nôm na thì chuỗi tạm trú ở địa chỉ xyz (trong bộ nhớ) còn biến a tạm chú ở địa chỉ abc, và a chỉ có nhiệm vụ nhớ giá trị xyz thôi.
Trong VBA thì VarPtr(a) trả về địa chỉ của biến a, tức giá trị abc. StrPtr(a) trả về địa chỉ tạm trú của chuỗi, tức giá trị xyz. Khi bạn muốn đọc ra chuỗi thì bạn viết vd. MsgBox a, nhưng sau cánh gà thì đã có những bước sau được thực hiện: nhẩy tới địa chỉ abc, tức nhẩy tới chỗ mà a tạm chú -> đọc ra 4 bai -> nhẩy tới địa chỉ bằng giá trị của 4 bai vừa đọc được, tức xyz, và đọc ra chuỗi.
Tất cả những cái tôi viết ở trên đều được làm sau cánh gà bởi code, Manager Memory Delphi (VBA). Bạn biết thì rất tốt, mà không biết cũng không sao. Bạn cứ
Dim a As String
a = "Ngay mai em đi."
MsgBox a
mà không cần biết sau cánh gà code và Manager Memory đã làm việc cật lực như thế nào để có kết quả dâng cho bạn. Bạn không cần biết là mỗi lần a thay đổi giá trị thì có thể nó sẽ thay đổi địa chỉ tạm trú trong bộ nhớ. Về phương diện người dùng bạn chỉ cần có giá trị mà không cần biết nó được "người ta" lấy từ đâu, lấy như thế nào. Tương tự như bạn chỉ thấy cô diễn viên má hồng môi đỏ mắt long lanh trên sân khấu, nhưng bạn không biết, không quan tâm, những ai sau cánh gà và đã đổ mồ hôi, thoa phấn má, tô môi, chải tóc, trang điểm như thế nào, để dâng cho bạn một cô diễn viên như thế.
String (long string) trong Delphi thực ra là Pointer. Bạn có thể viết
var
P: PChar;
...
a := 'Ngay mai em di.';
P := PChar(a);
showmessage(P^);
hoặc
a := 'Ngay mai em di.';
P := Pointer(a);
showmessage(P^);
Một câu cụt lủn như thế thì chịu không biết ý bạn thế nào.
Nếu chỉ 1 dòng cụt lủn thì khó có thể đoán ý bạn. Cũng như "bài trước" bạn chỉ tung lên 1 dòng thì không ai đoán được nguyên nhân lỗi đâu. Mà đoán được thì hơi khó. Chỉ khi tung lên toàn bộ code từ A đến Z thì may ra có người chỉ ra được nguyên nhân sảy ra lỗi.
Thế nếu trong trường hợp 1 bạn dùng xlToLeft có được không? Thực ra End chỉ đòi hỏi, chỉ chờ đợi 1 con số. Chỉ phải nhập đúng con số thôi chứ nó có phân biệt con số đó lấy từ kho của công ty A hay từ vườn của bà B đâu. Cứ đúng con số là được.
Kiểu ShortString luôn được phân 256 bai cho dù tùy từng thời điểm mà độ lớn của chuỗi có thể ngắn hơn rất nhiều. Biến ShortString luôn được phân cho 256 bai, trong đó bai đầu tiên được dùng để nhớ độ dài hiện hành của chuỗi, và chuỗi chỉ có thể dài nhất là 255 ký tự.
Biến d và f được phân cho 31 và 17. Dễ hiểu.
Tại sao chỉ có 4 bai được phân cho biến a? Thực ra một chuỗi bất kỳ thì không thể biết nó sẽ có độ lớn bao nhiêu để phân bộ nhớ cho nó. Vì thế "người ta" sẽ làm như sau:
- ở đâu đó trong bộ nhớ, vd. ở địa chỉ abc trong bộ nhớ, sẽ được "đặt đơn" 4 bai cho biến a.
- khi chuỗi a được thiết lập giá trị cụ thể thì ở đâu đó trong bộ nhớ, vd. ở địa chỉ xyz trong bộ nhớ, Manager Memory của Delphi sẽ phân cho một vùng đủ lớn để ghi chuỗi hiện hành.
- địa chỉ trong bộ nhớ của chuỗi hiện hành, tức xyz, được ghi vào 4 bai ở địa chỉ abc.
Nói nôm na thì a chỉ có 4 bai và ghi nhớ địa chỉ hiện hành của chuỗi, còn bản thân chuỗi nằm ở địa chỉ khác.
Nếu a thay đổi giá trị chuỗi nhiều lần thì địa chỉ xyz có thể thay đổi (chuỗi a thay đổi địa chỉ tạm trú) và địa chỉ mới (chỉ là con số) sẽ được ghi vào 4 bai ở địa chỉ abc trong bộ nhớ.
String trong VBA tương tự.
Dim a As String
thì thực ra a chỉ được phân cho 4 bai, giả sử 4 bai được phân cho a nằm ở địa chỉ abc trong bộ nhớ. Chuỗi sẽ được ghi ở địa chỉ xyz trong bộ nhớ, và giá trị xyz sẽ được ghi vào 4 bai nằm ở địa chỉ abc. Nói nôm na thì chuỗi tạm trú ở địa chỉ xyz (trong bộ nhớ) còn biến a tạm chú ở địa chỉ abc, và a chỉ có nhiệm vụ nhớ giá trị xyz thôi.
Trong VBA thì VarPtr(a) trả về địa chỉ của biến a, tức giá trị abc. StrPtr(a) trả về địa chỉ tạm trú của chuỗi, tức giá trị xyz. Khi bạn muốn đọc ra chuỗi thì bạn viết vd. MsgBox a, nhưng sau cánh gà thì đã có những bước sau được thực hiện: nhẩy tới địa chỉ abc, tức nhẩy tới chỗ mà a tạm chú -> đọc ra 4 bai -> nhẩy tới địa chỉ bằng giá trị của 4 bai vừa đọc được, tức xyz, và đọc ra chuỗi.
Tất cả những cái tôi viết ở trên đều được làm sau cánh gà bởi code, Manager Memory Delphi (VBA). Bạn biết thì rất tốt, mà không biết cũng không sao. Bạn cứ
Dim a As String
a = "Ngay mai em đi."
MsgBox a
mà không cần biết sau cánh gà code và Manager Memory đã làm việc cật lực như thế nào để có kết quả dâng cho bạn. Bạn không cần biết là mỗi lần a thay đổi giá trị thì có thể nó sẽ thay đổi địa chỉ tạm trú trong bộ nhớ. Về phương diện người dùng bạn chỉ cần có giá trị mà không cần biết nó được "người ta" lấy từ đâu, lấy như thế nào. Tương tự như bạn chỉ thấy cô diễn viên má hồng môi đỏ mắt long lanh trên sân khấu, nhưng bạn không biết, không quan tâm, những ai sau cánh gà và đã đổ mồ hôi, thoa phấn má, tô môi, chải tóc, trang điểm như thế nào, để dâng cho bạn một cô diễn viên như thế.
String (long string) trong Delphi thực ra là Pointer. Bạn có thể viết
var
P: PChar;
...
a := 'Ngay mai em di.';
P := PChar(a);
showmessage(P^);
hoặc
a := 'Ngay mai em di.';
P := Pointer(a);
showmessage(P^);
Tức là em chỉ cần xác định số byte chính xác. Nếu số byte dư, hay thiếu thì chắc lỗi phải không anh.
Tự cái Array là multi dynamic Array nên em chưa biết tính toán số Byte sao cho chinh xác
Cảm ơn anh rất nhiều.
Em co lên mạng tìm hiểu rồi mà dùng google dịch em đọc khó hiểu quá.
Tức là em chỉ cần xác định số byte chính xác. Nếu số byte dư, hay thiếu thì chắc lỗi phải không anh.
Tự cái Array là multi dynamic Array nên em chưa biết tính toán số Byte sao cho chinh xác
Bạn đang hỏi biến a kiểu là variant phải không? Biến variant có 2 byte đầu tiên chứa kiểu dữ liệu, tùy theo kiểu dữ liệu mà từ byte thứ 8 trở đi chứa giá trị hoặc địa chỉ của nội dung lưu trong biến a.
Bạn đang hỏi biến a kiểu là variant phải không? Biến variant có 2 byte đầu tiên chứa kiểu dữ liệu, tùy theo kiểu dữ liệu mà từ byte thứ 8 trở đi chứa giá trị hoặc địa chỉ của nội dung lưu trong biến a.
Em nhờ ông Google dịch dùm, nhiều lúc nó mong lung quá hihi. Bởi vậy hồi xưa không chịu học tiếng anh tốt
Với lại em không có học tin học, nhiều cái đụng vô mới mò khi biết rồi Ah thì ra đây là kiến thức cơ bản
Chúng ta đã biết lập trình VBA trong Excel với việc xử lý dữ liệu lớn rồi ghi lên bảng tính, bình thường chạy bị chậm. Phương pháp làm tăng tốc độ là xử lý trong mảng rồi điền cả mảng vào bảng tính. Thông thường khi làm với mảng, các công việc như xoá các phần tử trong mảng, chèn thêm dữ liệu...
Xin các anh chị giúp đỡ Code Gán các giá trị của một Range là các phần tử của Mãng Ví dụ: Tôi có các giá trị của Range("A1:A10"). Tôi muốn viết code để gán giá trị của các cells từ A1:A10 là các phần tử của Mãng Arr chẳn hạn. Xin cảm ơn các anh chị
www.giaiphapexcel.com
Nói vắn tắt thì 2 bai đầu (1 Word) là ghi VarType. Tiếp theo là 6 bai (3 Word) là reserved. 8 bai cuối là dữ liệu. Vd. nếu typ là numeric thì 8 bai sau là giá trị của numeric. Nếu vd. typ là string thì chỉ 4 bai là địa chỉ của string, còn bản thân string tạm trú ở nơi khác trong bộ nhớ. Nêu typ là Object thì cũng chỉ 4 bai là địa chỉ của Object tạm trú ở nơi khác. Những 4 bai này là Pointer tới string hoặc Object. Nhưng phải dùng 8 bai sau vì trong trường hợp numeric thì giá trị đọc luôn từ Variant. Mà khi typ là numeric DOUBLE thì double dùng 8 bai.
Hôm Mạnh có thử quậy ADO sử dụng phương thức Rst.GetRows
lấy dữ liệu cái Array 2D đó vào bộ nhớ xong gán xuống Sheet ... mục đích là bỏ qua 2 dòng For next xem nó như thế nào ???!!!
mò diết API + Linh tinh thì cuối cùng nó chỉ về mấy cái link GPE + nhiều nơi khác nó cũng cứ nói linh tinh ... cuối cùng cũng đang bỏ đó
Nhiều lúc mở help ra coi thấy nó rối hơn vì kiến thức của mình chưa đủ hiểu Help ... mò các VD mẫu diết xong mở help ra coi mới bất chợt thấy được ???!!!
coi bộ vậy chứ help trong chừng mực nào đó khó nhai lắm
Bạn có thể sử dụng hàm API CopyMemory để lấy các giá trị tại địa chỉ trong bộ nhớ để thử các trường trong biến variant. Ví dụ:
Mã:
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
Sub test1()
Dim a, Vtype&, arr(1 To 10) As Integer, addr&
'Variant a chua gia tri String
a = "abc"
CopyMemory Vtype, ByVal VarPtr(a), 2
CopyMemory addr, ByVal VarPtr(a) + 8, 4
CopyMemory ByVal VarPtr(arr(1)), ByVal addr, 6
End Sub
Sub test2()
Dim a, Vtype&, arr(1 To 10) As Byte, lng&
'Variant a chua gia tri Long
a = 1000&
CopyMemory Vtype, ByVal VarPtr(a), 2
CopyMemory lng, ByVal VarPtr(a) + 8, 4
End Sub
Khi chạy test1 ta thấy, 4 bytes tại địa chỉ VarPtr(a)+8 sẽ chứa địa chỉ của chuỗi unicode "abc" còn giá trị của biến lng sẽ được gán bằng số Long 1000.
Xin các anh chị giúp đỡ Code Gán các giá trị của một Range là các phần tử của Mãng Ví dụ: Tôi có các giá trị của Range("A1:A10"). Tôi muốn viết code để gán giá trị của các cells từ A1:A10 là các phần tử của Mãng Arr chẳn hạn. Xin cảm ơn các anh chị