Tach các cột tạo thành một mảng mới

Liên hệ QC

Yeuvoyeucon

Thành viên hoạt động
Tham gia
30/10/09
Bài viết
143
Được thích
23
Kính gửi anh chị và các bạn,

Giả sử em có bảng số liệu từ A đến cột G. Bình thường để add bảng dữ liệu này vào mảng thì ta dung lệnh sau

lr = .Range("A" & Rows.Count).End(xlUp).Row

arr = .Range("A2:G" & lr).Value

Bây giờ, em muốn tạo một mảng cũng trích từ bảng này nhưng chỉ lấy thứ tự theo các cột sau: Lấy cột A, Cột C, Cột G. Có cách viết như thế nào để viết chỗ này hay bắt buộc phải Redim từ mảng arr thành một mảng 3 chiều như ta vẫn thường làm ạ.
 

File đính kèm

  • Mang.xlsm
    9.6 KB · Đọc: 12
Quan trọng là mục đích CUỐI CÙNG là gì ấy. Chứ nêu tạo mảng chứa 3 cột đó không có ý nghĩa gì cả.
 
Upvote 0
Quan trọng là mục đích CUỐI CÙNG là gì ấy. Chứ nêu tạo mảng chứa 3 cột đó không có ý nghĩa gì cả.
Em đang cần làm một số bước mà cần 3 cột đó liền nhau ạ. Bình thường thì redim rồi em dán lại mảng 3 cột cần lấy này ra sheet. Rồi lại tính toán trên bảng này, như thế nó hơi dài dòng ạ.
 
Upvote 0
Em đang cần làm một số bước mà cần 3 cột đó liền nhau
Tôi biết bạn đang cần làm gì đó nên mới đăng bài hỏi.

Và cũng vì thế nên mới hỏi mục đích CUỐI CÙNG là gì để giải quyết '1 đập ăn quan'.
Bởi phương án kia mới là ý tưởng của bạn mà thôi, biết đâu đấy còn cách khác có khi không liên quan gì mảng này cả.
 
Upvote 0
Tôi biết bạn đang cần làm gì đó nên mới đăng bài hỏi.

Và cũng vì thế nên mới hỏi mục đích CUỐI CÙNG là gì để giải quyết '1 đập ăn quan'.
Bởi phương án kia mới là ý tưởng của bạn mà thôi, biết đâu đấy còn cách khác có khi không liên quan gì mảng này cả.
Ý của em là cần một mảng mới mà 3 cột đó liền nhau ạ. Làm theo bình thường redim, rồi lọc 3 cột đó ra từ mảng arr đầu thì đơn giản. Nhưng em muốn hỏi có cách nào viết cái chỗ này mà mảng nó vẫn hiểu là 3 cột đó không ạ
arr = .Range("Cột A, C, G" & lr).Value
 
Upvote 0
Bây giờ, em muốn tạo một mảng cũng trích từ bảng này nhưng chỉ lấy thứ tự theo các cột sau: Lấy cột A, Cột C, Cột G. Có cách viết như thế nào để viết chỗ này hay bắt buộc phải Redim từ mảng arr thành một mảng 3 chiều như ta vẫn thường làm ạ.
mảng 3 chiều tức là Redim b(1 To n1, 1 To n2, 1 To n3)
Tôi chưa thấy kiểu nào trong GPE bắt buộc phải pàm vậy cả.

Chép lại mảng cách cột là công việc khá vô duyên.
Người ta chép lại cả mảng rồi delete những cột không cần thiết.
 
Upvote 0
mảng 3 chiều tức là Redim b(1 To n1, 1 To n2, 1 To n3)
Tôi chưa thấy kiểu nào trong GPE bắt buộc phải pàm vậy cả.
Thớt 'lỡ tay' gõ vậy thôi anh. :)

Chép lại mảng cách cột là công việc khá vô duyên.
Người ta chép lại cả mảng rồi delete những cột không cần thiết.

Em đoán thớt cần lấy 3 cột ở xa nhau kia sang một sheet/range khác (và không muốn dùng vòng lặp xét từng dòng). Mà hỏi mãi không chịu hé răng ra.
Thớt mà nói ra thì 2 giây là xong lâu rồi.
 
Upvote 0
Thớt 'lỡ tay' gõ vậy thôi anh. :)



Em đoán thớt cần lấy 3 cột ở xa nhau kia sang một sheet/range khác (và không muốn dùng vòng lặp xét từng dòng). Mà hỏi mãi không chịu hé răng ra.
Thớt mà nói ra thì 2 giây là xong lâu rồi.
Em không hiểu ý của anh hỏi, chứ mong muốn của em chỉ là: Có cách nào biểu diễn arr = .Range("Cột A, C, G" & lr).Value hay phải làm Redim một mảng mới và dán nó ra sheet và làm tiếp tục trên nó.
Cái này em hỏi nó giống như ở SQL mình dùng cấu trúc để tạo ra một bảng và lại xử lý tiếp trên nó.
WITH expression_name[(column_name [,...])]
AS
(CTE_definition)
SQL_statement;
 
Upvote 0
Upvote 0
Trong VBA dùng Index() là lấy được cột.
...
Không dễ như vậy.
Có hai cách để làm:
1. Union các cột lại thành một range chính.
Kế đó đọc range này vào một array.
Bởi vì Union là một mảng 3 chiều, mỗi vùng range trong union là một area. Cách đọc trực tiếp chỉ lấy được area 1. Phải dùng vòng lặp để lấy từng area vào từng mảng con của array (array kết quả là một array răng cưa - jagged array)
Ghi ngược lại cũng là qua vòng lặp, từng mảng con.
Cáchn này đòi hỏi trình đô hiểu biết về mảng khá cao.
2. Dùng hàm Evaluate để tính một biểu thức công thức trên bảng tính. Công thức này có thể dùng Index hay dễ hơn là dùng hàm choose để ghép nhiều cột lại thành 1 mảng 2 chiều.
Cột này đòi hỏi trình độ về mảng tuonwg đói những trình độ hiểu Evaluate khá sâu.
(lưu ý là tôi dùng từ ngữ rất chính xác. Khi tôi nói trình độ hiểu biết cao là tôi muốn nói cao - tức biết sử dụng rất thuần thục, khi nói sâu là tôi muốn nói sâu, tức căn bản rất chắc)

Chú thích: cái chủ trương "càng nhiều bài càng tốt, càng nhiều người mới càng quý" của chủ diễn đàn đi theo cái phản ứng phụ là làm giảm chất lượng.
Một trong những phản ứng phụ là người trả lời chịu khó phân tích, giải thích câu trả lời của mình. Trong khi người hỏi không buồn cải tiến cách đặt câu cú, cách trình bày vấn đề của mình.
Thế giới GPE có ngược ngạo thế đấy. Người không có nhiều nhu cầu cải tiến thì luôn cố gắn. Ngwoif đáng lẽ phải luon cải tiến kỹ năng giao tiếp thì hời hợt, coi diễn đàn như cái chợ, cần món gì thì tạt vào mua. Lắm lúc thiếu suyn nghĩ đến mức cần cá mà vào chợ hỏi mua thịt.
 
Upvote 0
Dùng Index() lấy được cột mà anh.

PHP:
Option Explicit

Sub vidu()
    Const sRngData = "A2:E10"
    Const sCellTarget = "H2"
    Dim data As Variant, listIndex As Variant, numRows As Long, item As Variant, iCol As Long
    data = Sheet1.Range(sRngData).Value
    listIndex = VBA.Array(1, 3, 5)  'Lay cot A, C, E '
    numRows = UBound(data, 1)
    For Each item In listIndex
        Sheet1.Range(sCellTarget).Offset(0, iCol).Resize(numRows, 1).Value = Application.index(data, , VBA.CLng(item))
        iCol = iCol + 1
    Next item
End Sub
 
Upvote 0
Dùng Index() lấy được cột mà anh.

PHP:
Option Explicit

Sub vidu()
    Const sRngData = "A2:E10"
    Const sCellTarget = "H2"
    Dim data As Variant, listIndex As Variant, numRows As Long, item As Variant, iCol As Long
    data = Sheet1.Range(sRngData).Value
    listIndex = VBA.Array(1, 3, 5)  'Lay cot A, C, E '
    numRows = UBound(data, 1)
    For Each item In listIndex
        Sheet1.Range(sCellTarget).Offset(0, iCol).Resize(numRows, 1).Value = Application.index(data, , VBA.CLng(item))
        iCol = iCol + 1
    Next item
End Sub
Nó cũng là chép lại từng cột như mảng răng cưa như tôi nói ở bài trên. Thà dùng thẳng mảng răng cưa ít nhầm lẫn hơn.
 
Upvote 0
Kính gửi anh chị và các bạn,

Giả sử em có bảng số liệu từ A đến cột G. Bình thường để add bảng dữ liệu này vào mảng thì ta dung lệnh sau

lr = .Range("A" & Rows.Count).End(xlUp).Row

arr = .Range("A2:G" & lr).Value

Bây giờ, em muốn tạo một mảng cũng trích từ bảng này nhưng chỉ lấy thứ tự theo các cột sau: Lấy cột A, Cột C, Cột G. Có cách viết như thế nào để viết chỗ này hay bắt buộc phải Redim từ mảng arr thành một mảng 3 chiều như ta vẫn thường làm ạ.
Cái này dùng mảng trong mảng là được, có cái là khi tra cứu phần tử, các chỉ số có hơi khác so với mảng 2 chiều bình thường
 
Upvote 0
Minh hoạ cách 2 như tôi nói ở bài #11

View attachment 267963
Em đã thử với dữ liệu và code chạy đúng ý em ạ. NHưng có một vấn đề là dòng cuối lastrow thì mình có thể viết thế nào anh !. Em đã thử như dưới mà không được ạ.

Sub tt()
With Sheet1
Dim arr(), lr&
lr = .Range("A" & Rows.Count).End(xlUp).Row
arr = Evaluate("Choose({1,2,3},"A1:A"&lr,"C1:C"&lr,"G1:G"&lr)")
.Range("K2").Resize(lr, 3).Value = arr 'Thử in ra sheet
End With


End Sub
 
Upvote 0
Hàm Evaluate chỉ nhận một biểu thức có giá trị là string:

a = Evaluate(Replace("Choose({1,2,3}, A1:A<sd>,C1:C<sd>,G1:G<sd>)", "<sd>", CStr(lr)))

Nếu không muón dùng Evaluate thì cũng có thể dùng hàm Application.Choose. Nhưng cách gọi hơi rắc rối hơn một chút:

a = Application.Choose([ { 1, 2, 3 } ], Range("A1:A" & lr), Range("C1:C" & lr), Range("G1:G" & lr))
Lưu ý là VBA không chấp nhận dấu { }, muốn gọi biểu thức có dấu này thì phải gói qua Evaluate. Trong biểu thức trên, hàm Evaluate được viết tắt bằng [ ].

Lưu ý quan trọng: như tôi đã nhắc ở bài #11. Lấy giá trị kiểu này hơi nguy hiểm, người dùng nên check trước là hàm choose ở trên trả về giá trị Value hay Value2.
 
Lần chỉnh sửa cuối:
Upvote 0
Hàm Evaluate chỉ nhận một biểu thức có giá trị là string:

a = Evaluate(Replace("Choose({1,2,3}, A1:A<sd>,C1:C<sd>,G1:G<sd>)", "<sd>", CStr(lr)))

Nếu không muón dùng Evaluate thì cũng có thể dùng hàm Applicasiton.Choose. Nhưng cách gọi hơi rắc rối hơn một chút:

a = Application.Choose([ { 1, 2, 3 } ], Range("A1:A" & lr), Range("C1:C" & lr), Range("G1:G" & lr))
Lưu ý là VBA không chấp nhận dấu { }, muốn gọi biểu thức có dấu này thì phải gói qua Evaluate. Trong biểu thức trên, hàm Evaluate được viết tắt bằng [ ].

Lưu ý quan trọng: như tôi đã nhắc ở bài #11. Lấy giá trị kiểu này hơi nguy hiểm, người dùng nên check trước là hàm choose ở trên trả về giá trị Value hay Value2.
Code chạy đúng rồi ạ. Em cảm ơn anh nhiều ạ .
 
Upvote 0
Nó cũng là chép lại từng cột như mảng răng cưa như tôi nói ở bài trên.
Theo em gọi là mảng răng cưa có thể tạo cảm giác phức tạp và bị giới hạn (tương tự gọi là 'mảng trong mảng').
Nếu nắm chắc định nghĩa về mảng sẽ linh hoạt hơn.
Đơn giản phần tử của mảng có thể là 1 giá trị, object, array hay bất kể loại dữ liệu nào đó, rồi trong mỗi phần tử đó lại chứa những kiểu dữ liệu khác đan xen trong nó. Điển hình như kiểu dữ liệu json.
Có vẻ những thành viên đi trước tạo ra những ảnh hưởng nhất định tới những thành viên sau về cách tiếp cận lý thuyết, hoặc ít có cơ hội/ bài toán cần xây dựng mô hình phức tạp kia.


Thà dùng thẳng mảng răng cưa ít nhầm lẫn hơn.
Em thấy dùng Evaluate, Applicasiton.Choose phức tạp hơn dùng Index() rồi.
Chưa kể cách dùng Index() còn áp dụng trường hợp khi có mảng kết quả cần ghi xuống những cột không liên tiếp.
 
Upvote 0
...
Đơn giản phần tử của mảng có thể là 1 giá trị, object, array hay bất kể loại dữ liệu nào đó, rồi trong mỗi phần tử đó lại chứa những kiểu dữ liệu khác đan xen trong nó. Điển hình như kiểu dữ liệu json.
Có vẻ những thành viên đi trước tạo ra những ảnh hưởng nhất định tới những thành viên sau về cách tiếp cận lý thuyết, hoặc ít có cơ hội/ bài toán cần xây dựng mô hình phức tạp kia.
...
Kiểu dữ liệu JSON là kiểu dữ liệu của JavaScript. Nó là Object chứ phông phải mảng.

Mảng là lối cấu trúc cổ điển nhất trong lập trình. Vì cổ điển cho nên nó bắt buộc phải rất hiệu quả (trong giới hạn của nó), đặc biệt là các phần tử bắt buộc phải liên tiếp nhau trong bộ nhớ.

Về sau này, các ngôn ngữ mới như JavaScript, Python ỷ trượng vào sức mạnh của máy đời sau (có nhớ ngày xưa khi Intel ra 80286 thay thế 8088/8086 đã là rầm rộ, Pentium thay 80486 lại càng dữ dội hơn - Pent là 5, chắc ý họ nói 80586) nên dùng cấu trúc dạng XML cho dễ parse. VBx, VBA bắt buộc phải thêm mấy cái COM để đối phó.
Riêng Python ỷ trượng vào đống thư viện khổng lồ mà các tay hảo tâm viết (thường thì bằng C nên rất hiệu quả). Đã qua sàng lọc ngon lành cho nên càng ngày càng mạnh. Và nhất là đống cấu trúc dữ liệu, các giao diện trong thư viện rất mạnh. Chính Python thì nó chỉ là một cái sàn viết script thôi.
Sức mạnh của Python chính thức là do nhóm cha đẻ ra nó đã có cái nhìn khách quan (tôi nghĩ qua kinh nghiệm GCC) cho nên họ đặt ngôn ngữ này có thể nhập (import) thư viện hết sức dễ dàng.
 
Upvote 0
Web KT
Back
Top Bottom