Vấn đề khi gán từ mảng xuống range ?

Liên hệ QC

Nguyen Rem

Tất cả chỉ là đưa ra quyết định đúng đắn
Tham gia
23/2/22
Bài viết
211
Được thích
30
Giới tính
Nữ
Em chào các anh chị ^^
Hiện tại em đang ôn tập lại một chút về mảng thì em gặp một số vấn đề sau mong anh chị giúp đỡ em
Bài toán em đặt ra chỉ đơn giản là chuyển từ hàng thành cột nhưng làm theo 3 cách (Lưu ở trong Module 1)

Vấn đề:
Lúc chạy đến chỗ dòng màu đỏ thì nó hiện ra giá trị từ ô B2 đến ô R2 đều là b (Kết quả không mong muốn)
1655447891045.png
Sau đó em tiếp tục thử bằng cách dùng hàm transpose thì nó lại được :
1655449161462.png
So sánh về ý tưởng thì hai cách đều giống nhau nhưng mà cách dùng hàm Transpose như trên có gì đặc biệt mà nó lại ra kết quả mong muốn ?
Mong cách anh chị giúp em giải thích với ạ :>
 

File đính kèm

  • Array.xlsm
    18.6 KB · Đọc: 5
Mảng có kích thước 17 dòng x 1 cột
Giờ hãy thử gán xuống
- B2:B20
- B2: B10
- B2
- B2:C2
- B2:X2
Rồi rút ra bài học.
Gán xuống B2.Resize(,n) tức là gán xuống n lần cái gạch đầu dòng thứ 3
Những cái này là rất căn bản của mảng. Tôi thấy bạn học rất ôm đồm nhiều lĩnh vực, thế mà mỗi lĩnh vực lại mất căn bản.
 
Upvote 0
Trong cách 1 Arr là mảng 2 chiều có nhiều HÀNG 1 CỘT nên phải là:

Sheet1.Range("B2).Resize(Ubound(Arr, 1)).Value = Arr

Trong cách 2 Arr là mảng 1 CHIỀU có UBound(Arr, 1) phần tử nên phải là:

Sheet1.Range("B3").Resize(, UBound(Arr, 1)).Value = Arr

Cách 2 là bạn chuyển CỘT(cột A2:A18) thành HÀNG (B3:R3)

Vấn đề là bạn muốn gì. Bài toán thì là: "chuyển từ HÀNG thành CỘT". Trong khi đó xuất phát điểm là Rng thì lại là vùng có 1 CỘT (A2:A19), và chuyển thành 1 HÀNG (B3:R3). Như thế thì bài toán phải là: "chuyển từ CỘT thành HÀNG" chứ.
 
Upvote 0
Mảng có kích thước 17 dòng x 1 cột
Giờ hãy thử gán xuống
- B2:B20
- B2: B10
- B2
- B2:C2
- B2:X2
Rồi rút ra bài học.
Gán xuống B2.Resize(,n) tức là gán xuống n lần cái gạch đầu dòng thứ 3
Những cái này là rất căn bản của mảng. Tôi thấy bạn học rất ôm đồm nhiều lĩnh vực, thế mà mỗi lĩnh vực lại mất căn bản.
Không phải do thớt bỏ qua căn bản mảng. Về căn bản mảng thì tôi tin là thớt cũng đủ rồi.
Chỉ là:
1. Lúc học bài, thớt bỏ qua, coi thường bài "liên hệ giữa array (mảng) và range".
2. Thớt rớ vào phần thực hành mà tưởng như nó là lý thuyết cho nên mới mò mẫm cho sâu rồi đâm thắc mắc. Nhiều bạn khác ở GPE này đâu có căn bản mấy về mảng, vẫn làm chuyện copy qua lại giữa mảng và range một cách trơn tru.

Lý thuyết:
Excel là bảng tính trải rộng. Trải rộng có nghĩa là gì? Là 2 chiều.
Vì vậy Range trong Excel luôn mặc định là 2 chiều - cột và dòng.
Lưu ý từ "mặc định" trên. Ngoài mặc định thì Range cũng có thể là 1 ô (cell), không có chiều gì cả; hoặc là Union của nhiều Ranges, 3 chiều.

VBA có hai phương thức mặc định liên hệ giữa Range của Worksheet và Array (mảng):
1. Phương thức copy từ Range qua Array: a() = Range(...).Value toán tử phép gán = gọi phương thức mặc điịnh này
2. Phương thức copy từ Array qua Range: Range(...).Value = a() toán tử phép gán = gọi phương thức mặc điịnh này
Trong 2 phép toán trên:
- Array luôn luôn là mảng 2 chiều. Dòng của Range là dòng của Array, cột của Range là cột của Array. Nếu Range chỉ có một dòng hay một cột thì Array cũng vẫn là mảng 2 chiều, với chiều thứ nhất (1 dòng) hoặc thứ hai (1 cột) là (1 To 1). Trường hợp ngoại lệ duy nhất là khi Range chỉ gồm 1 ô/cell thì vế kia là một Variant (1 trị) thay vì mảng.
- Value là thuộc tính mặc định của Range.
- Mảng copy từ Range ra luôn luôn có chỉ số khởi đầu là 1. Mặc dù phần lớn các hàm làm việc với mảng của VBA mặc định mảng chỉ số khởi đầu là 0.

Transpose là hàm chuyển đảo ma trận. Người viết code VBA lợi dụng tính chất của Transpose để ép Range làm việc với mảng 1 chiều.
Đây chỉ là một xảo thuật của người viết code, không phải là lý thuyết. Muốn biết nó làm việc ra sao thì chỉ có cách tự tư duy ra các trường hợp (scenarios) khác nhau rồi viết code thử.
Nếu thử 3 lần chưa thấy thì 10 lần, 20 lần. Đã là xảo thuật thì nó thuộc về thực hành.

Chú thích:
(i) Tôi quen cách nói chuyện của các ngôn ngữ dòng họ C, trong đó phép gán là một toán tử.
(ii) Theo tình thần hướng đối tượng thì các toán tử làm việc với đối tượng có thể ẩn phương thức thực hiện những công việc nằm ngoài phép toán thông thường. Range là một đối tượng.
 
Lần chỉnh sửa cuối:
Upvote 0
Dạ vâng ạ ! Em đã đọc bài của hai anh rồi ạ . Em nhận ra là mình đang hiểu sai khá nặng về Resize .
Vấn đề là bạn muốn gì
Thật ra là em đang thắc mắc về cái câu lệnh Application.Transpose(Rng.Value)
1655458246709.png
Nên em đã cố gắng tạo ra một phản ví dụ để hỏi các anh .
Lúc đầu thì em nghĩ là cái Hàm Transpose có khả năng hoán đổi hai chiều của mảng rồi tự động chuyển một hàng thành cột , cột hành hàng nhưng mà dựa vào câu trả lời của anh batman1 thì em nhận ra là nó chỉ có khả năng biến mảng hai chiều thành mảng một chiều xong rồi dựa vào cái resize để gán từ mảng xuống một vùng ô
1655459097046.png
 
Upvote 0
câu trả lời của anh batman1 thì em nhận ra là nó chỉ có khả năng biến mảng hai chiều thành mảng một chiều xong rồi dựa vào cái resize để gán từ mảng xuống một vùn
Không phải.

- Transpose biến vùng 1 CỘT nhiều HÀNG thành mảng 1 CHIỀU có nhiều phần tử. Ta nói nhiều phần tử chứ không nói nhiều CỘT hay nhiều HÀNG vì mảng 1 CHIỀU là mảng 1 chiều, không có khái niệm cột hàng. Nhiều người gọi là mảng ngang, nhưng làm quái gì có khái niệm mảng NGANG, DỌC. Chỉ có khái niệm mảng 2 chiều (số cột, số hàng) hoặc mảnng 1 CHIỀU (số phần tử).

- Transose biến vùng 1 HÀNG nhiều CỘT thành mảng 2 CHIỀU.

Tóm lại:
- vùng 1 HÀNG nhiều CỘT -> luôn thành mảng 2 CHIỀU
- vùng 1 CỘT nhiều HÀNG -> luôn thành mảng 1 chiều.
- vùng nhiều CỘT nhiều HÀNG -> luôn thành mảng 2 CHIỀU

Tức nếu vùng nhiều CỘT thì luôn thành mảng 2 chiều.
---------
Vì bạn dùng "điểm xuất phát" là Rng nên tôi dùng khái niệm vùng chứ không dùng khái niệm mảng khi nói về "điểm xuất phát".
 
Lần chỉnh sửa cuối:
Upvote 0
Còn trường hợp ngoại lệ nữa anh.

PHP:
Range("A1:C1").Value = VBA.Array(1, 2, 3)
Không hẳn. Đấy là VBA tự ép range nhận mảng 1 chiều.

Thử như vầy thấy rõ hơn:
[a1:c1] = [ { 1, 2, 3 } ] ' tương đương mảng 1 dòng 3 cột
[a1:a3] = [ { 1; 2; 3 } ] ' tương đương mảng 1 cột 3 dòng
Sau đó xóa đi và thử:
[a1:c1] = Application.Transpose([ { 1; 2; 3 } ])
Và đây chính là cái chỗ mà hàm Transpose chen vào để chuyển qua chuyển lại.
(bởi vậy tôi mới nói 3 lần thử chưa thấy thì 10 lần)
 
Upvote 0
Tôi đã giải thích cho bạn với tham số của Transpose là VÙNG - Range.

Tôi cho bạn luôn khi tham số của Transpose là MẢNG.

- mảng 2 CHIỀU có 1 CỘT (số HÀNG tùy ý) vd. arr(1 To 3, 1 To 1), arr(1 To 1, 1 To 1) -> Transpose trả về mảng 1 CHIỀU
- mảng 2 CHIỀU có nhiều CỘT (số HÀNG tùy ý) vd. arr(1 To 1, 1 To 4) arr(1 To 3, 1 To 4) -> Transpose trả về mảng 2 CHIỀU
- mảng 1 CHIỀU vd. arr(1 To 3), Array(1, 2, 7, 9, 4) -> Transpose trả về mảng 2 CHIỀU.

Thế là xong toàn bộ. Khỏi phải hỏi lên hỏi xuống.
 
Upvote 0
Không phải do thớt bỏ qua căn bản mảng. Về căn bản mảng thì tôi tin là thớt cũng đủ rồi.
Chỉ là:
1. Lúc học bài, thớt bỏ qua, coi thường bài "liên hệ giữa array (mảng) và range".
Theo tôi, lấy dữ liệu vào mảng bằng bao nhiêu cách (trong đó có lấy từ sheet) và trả kết quả về (sheet) là 1 phần của "căn bản" lý thuyết.
Mảng 1 chiều, hai chiều, ... là căn bản
Khi gán mảng nhiều phần tử xuống vùng nhỏ hơn kích thước mảng, lớn hơn kích thước mảng, là 1 ô, gán vùng không đúng chiều ra kết quả gì cũng là căn bản thực hành.
Trong bài trên tôi viết "Gán xuống B2.Resize(,n) tức là gán xuống n lần cái gạch đầu dòng thứ 3" là giải thích rất rõ, không biết người này có đọc hay không. Chỉ nhắc dến "hai anh", chắc 2 anh này tử tế hơn tôi chăng.
 
Upvote 0
Theo tôi, lấy dữ liệu vào mảng bằng bao nhiêu cách (trong đó có lấy từ sheet) và trả kết quả về (sheet) là 1 phần của "căn bản" lý thuyết.
Mảng 1 chiều, hai chiều, ... là căn bản
Khi gán mảng nhiều phần tử xuống vùng nhỏ hơn kích thước mảng, lớn hơn kích thước mảng, là 1 ô, gán vùng không đúng chiều ra kết quả gì cũng là căn bản thực hành.
Trong bài trên tôi viết "Gán xuống B2.Resize(,n) tức là gán xuống n lần cái gạch đầu dòng thứ 3" là giải thích rất rõ, không biết người này có đọc hay không. Chỉ nhắc dến "hai anh", chắc 2 anh này tử tế hơn tôi chăng.
Em có đọc hết ạ(Em quên mất nhắc tới anh --tại trong lúc đang tập chung vào cách giải quyết bài làm-- nhưng mà em có thả tim vào bài của anh mà :>) . Em đang tạo phản ví dụ nhưng mà nó hơi dài mong các anh chờ em thêm ạ
 
Upvote 0
Em có một thắc mắc, thành viên này luôn được ưu ái và thiên vị hơn nhiều thành viên khác rất nhiều………Mặc dù ưu ái hay thiên vị là quyền của anh chị…….
Phải chăng đây là một giai nhân tuyệt sắc ?
 
Upvote 0
Em có một thắc mắc, thành viên này luôn được ưu ái và thiên vị hơn nhiều thành viên khác rất nhiều………Mặc dù ưu ái hay thiên vị là quyền của anh chị…….
Phải chăng đây là một giai nhân tuyệt sắc ?
Em xin lỗi nhưng mà liệu anh có thể tạm gác lại câu hỏi này cho đến khi câu trả lời của em được hoàn thành được không ạ . Anh cũng thấy là tinh thần xây dựng chủ đề này đang được đẩy lên mức cao sao mà anh nỡ cho nó tụt dốc thảm hại đến vậy ?
 
Upvote 0
Em có một thắc mắc, thành viên này luôn được ưu ái và thiên vị hơn nhiều thành viên khác rất nhiều………Mặc dù ưu ái hay thiên vị là quyền của anh chị…….
Phải chăng đây là một giai nhân tuyệt sắc ?
Nhận thức của bạn đầy mặc cảm và thành kiến.
Việc "giai nhân tuyệt sắc" đâu có thành vấn đề khi mà tôi chưa tuyên bố với quý vị về sở thích giới tính của tôi?
Vả lại, ở đây cũng có vài bạn nam được tôi chú ý nhiều, bạn cho rằng tôi thích đờn ông?

Lý do tôi không tẩy chay thành viên này là vì:
1. Cho đến giờ phút này, đương sự vẫn ăn nói tương đối lịch sự.
2. Đương sự hỏi để tìm hiểu chứ đâu có nhờ giúp làm giùm từ a đến z như phần lớn các thớt ở đây.
3. Có những câu hỏi tôi trả lời chung giúp kiến thức nhiều bạn khác.
4. Có những câu tôi trao đổi kiến thức với một vài người khác.

Em xin lỗi nhưng mà liệu anh có thể tạm gác lại câu hỏi này cho đến khi câu trả lời của em được hoàn thành được không ạ . Anh cũng thấy là tinh thần xây dựng chủ đề này đang được đẩy lên mức cao sao mà anh nỡ cho nó tụt dốc thảm hại đến vậy ?
Đáng lẽ bạn nên làm ngơ. Học thì lo học. Hỏi bài thì lo hỏi bài. Đi đôi co với những chuyện khác là chơi dại. Có thắng cũng chẳng làm ai thích mình hơn. Mà lỡ lời một vài điểm thì lại mất bạn.

Lời này tôi từng khuyên một vài người rồi. Có một người tôi chưa kịp khuyên thì đã xảy ra chuyện không hay.
 
Upvote 0
Em có chuẩn bị một File chắc nó khái quát lại toàn bộ những dữ kiện mà các anh đã nêu ra từ bài #1 đến bài #7 Trừ bài #6(do em vẫn chưa có thời gian tìm hiểu sâu)--File này em định thắc mắc cơ nhưng mà trong lúc đặt câu hỏi thì cũng đã giải quyết được rồi nên thôi :>-- .
Em cũng biết có thể các anh không có hứng nghe nữa vì một số tác động bên ngoài nhưng mà mong các anh vẫn cố đọc để tìm ra lỗi sai của em ^^ (các anh chạy tất cả các module bằng phím F8 để hiểu ý em đang muốn nói là gì)

Như em biết là lúc gán một vùng có số ô lớn hơn 1 vào một biến mảng thì lập tức biến mảng đó sẽ trở thành biến mảng có hai chiều
Từ Module 1 đến Module 3 là quá trình em chạy thử code để kiểm tra xem:
  • Liệu khi gán ngược biến mảng hai chiều này vào một vùng thì các trường hợp có gì khác nhau không và kiết quả rút ra được là gì?
  • Lúc gán mảng 1 chiều (sau khi dùng transpose để chuyển ) thì nó như thế nào ? Có khác gì ở trên không?
Đi vào vấn đề:
1. Trong trường hợp vùng có nhiều hàng và một cột duy nhất:
Ở trong Module1:
1655483649759.png
Như anh batman1 đã đề cập ở trên .
Kết quả lúc gán mảng hai chiều vào ra không đúng theo mong muốn là vì:
Arr là mảng 2 chiều có nhiều HÀNG 1 CỘT nên phải là:

Sheet1.Range("B2).Resize(Ubound(Arr, 1)).Value = Arr
Và kết quả khi chuyển vùng 1 cột nhiều hàng bằng hàm transpose thành mảng 1 chiều có nhiều phẩn tử ( chuyển mảng hai chiều thành 1 chiều) Nó ra kết quả mong muốn là do:
mảng 1 CHIỀU có nhiều phần tử

2. Trong trường hợp vùng có nhiều cột và một hàng duy nhất:
Ở trong Module2:
1655483723478.png
Thì kết luận rút ra là :
Lúc gán mảng hai chiều để ra kết quả mong muốn thì câu lệnh như sau:
.Worksheets("2").Range("A5").Resize(1, UBound(Brr, 2)).Value = Brr()
chứ không được: (do đây là mảng có nhiều cột và chỉ có duy nhất một dòng
.Worksheets("2").Range("A5").Resize(UBound(Brr, 2)).Value = Brr()

Và kết quả khi chuyển vùng n cột và 1 hàng bằng hàm transpose sẽ thành mảng 2 chiều với mảng mới có độ lớn là (1 To 1 , 1 To n)

3. Trong trường hợp vùng có m cột và n hàng:
Ở trong Module3:

1655482636559.png
Thì kết luận rút ra là :
Lúc gán mảng hai chiều để ra kết quả mong muốn thì câu lệnh như sau:
Mã:
.Worksheets("3").Range("A5").Resize(UBound(Crr()) , 1) , UBound(Crr(), 2).Value = Crr()
chứ không được: (do đây là mảng có m cột và n dòng
Mã:
.Worksheets("3").Range("A5").Resize(1, UBound(Crr(), 2).Value = Application.Transpose(Crr())
hay
Mã:
.Worksheets("3").Range("A5").Resize(UBound(Crr(), 1) , 1).Value = Application.Transpose(Crr())

Và kết quả khi chuyển vùng m cột n hàng bằng hàm transpose thành mảng 2 chiều có độ lớn là:
(1 To n , 1 To m)

Giờ cũng đã khá muộn(em ngồi từ 17h--còn chưa ăn hic--) nên em upload tạm lên mong các anh cho em nhận xét và khắc phục lỗi . Bây giờ chắc em đi gọi ship đồ ăn ^^
Bài đã được tự động gộp:

Theo tôi, lấy dữ liệu vào mảng bằng bao nhiêu cách (trong đó có lấy từ sheet) và trả kết quả về (sheet) là 1 phần của "căn bản" lý thuyết.
Mảng 1 chiều, hai chiều, ... là căn bản
Khi gán mảng nhiều phần tử xuống vùng nhỏ hơn kích thước mảng, lớn hơn kích thước mảng, là 1 ô, gán vùng không đúng chiều ra kết quả gì cũng là căn bản thực hành.
Trong bài trên tôi viết "Gán xuống B2.Resize(,n) tức là gán xuống n lần cái gạch đầu dòng thứ 3" là giải thích rất rõ, không biết người này có đọc hay không. Chỉ nhắc dến "hai anh", chắc 2 anh này tử tế hơn tôi chăng.
Em có đọc bài của anh rồi (Thậm chí đọc rất kĩ) . Cái trên chỉ là do em bất cẩn trong lúc viết thôi anh ạ ^^
Minh chứng :
1655483838890.png
1655483879665.png
Nên anh vẫn rất tử tế hi :>
 

File đính kèm

  • Array.xlsm
    25.5 KB · Đọc: 3
Lần chỉnh sửa cuối:
Upvote 0
Không phải.

- Transpose biến vùng 1 CỘT nhiều HÀNG thành mảng 1 CHIỀU có nhiều phần tử. Ta nói nhiều phần tử chứ không nói nhiều CỘT hay nhiều HÀNG vì mảng 1 CHIỀU là mảng 1 chiều, không có khái niệm cột hàng. Nhiều người gọi là mảng ngang, nhưng làm quái gì có khái niệm mảng NGANG, DỌC. Chỉ có khái niệm mảng 2 chiều (số cột, số hàng) hoặc mảnng 1 CHIỀU (số phần tử).

- Transose biến vùng 1 HÀNG nhiều CỘT thành mảng 2 CHIỀU.

Tóm lại:
- vùng 1 HÀNG nhiều CỘT -> luôn thành mảng 2 CHIỀU
- vùng 1 CỘT nhiều HÀNG -> luôn thành mảng 1 chiều.
- vùng nhiều CỘT nhiều HÀNG -> luôn thành mảng 2 CHIỀU

Tức nếu vùng nhiều CỘT thì luôn thành mảng 2 chiều.
---------
Vì bạn dùng "điểm xuất phát" là Rng nên tôi dùng khái niệm vùng chứ không dùng khái niệm mảng khi nói về "điểm xuất phát".
Tôi đã giải thích cho bạn với tham số của Transpose là VÙNG - Range.

Tôi cho bạn luôn khi tham số của Transpose là MẢNG.

- mảng 2 CHIỀU có 1 CỘT (số HÀNG tùy ý) vd. arr(1 To 3, 1 To 1), arr(1 To 1, 1 To 1) -> Transpose trả về mảng 1 CHIỀU
- mảng 2 CHIỀU có nhiều CỘT (số HÀNG tùy ý) vd. arr(1 To 1, 1 To 4) arr(1 To 3, 1 To 4) -> Transpose trả về mảng 2 CHIỀU
- mảng 1 CHIỀU vd. arr(1 To 3), Array(1, 2, 7, 9, 4) -> Transpose trả về mảng 2 CHIỀU.

Thế là xong toàn bộ. Khỏi phải hỏi lên hỏi xuống.
Bây giờ em nhìn lại toàn bộ bài viết của anh và ngẫm lại toàn bộ quá trình tạo cái file ấy thấy mình thật stupid(ngu ngốc) :>
Các anh có thể không quan tâm đến bài số #15 cũng được :> Tại nó hơi bị ngố ấy nhưng mà em vẫn có một thắc mắc muốn hỏi anh là
Các giá trị trả về của hàm transpose trong hai trường hợp (nếu tham số là một mảng hoặc vùng ô) là mảng một chiều hoặc hai chiều thì cái đó là học thuộc chứ không chứng minh được đúng không anh ^^
 
Upvote 0
Như em biết là lúc gán một vùng có số ô lớn hơn 1 vào một biến mảng thì lập tức biến mảng đó sẽ trở thành biến mảng có hai chiều
Chính xác
1. Trong trường hợp vùng có nhiều hàng và một cột duy nhất:
Ở trong Module1:
Arr là mảng 2 CHIỀU có 1 CỘT và 11 HÀNG. Vậy muốn gán xuống sheet TOÀN BỘ mảng Arr thì phải "đập" nó vào VÙNG có 1 CỘT và 11 HÀNG. Tức nếu bắt đầu từ C3 thì phải đập vào VÙNG C3:C13. Tức
Mã:
.Worksheets("1").Range("C3").Resize(UBound(Arr, 1)).Value = Arr()

hoặc

.Worksheets("1").Range("C3").Resize(UBound(Arr, 1), 1).Value = Arr

Nhưng không có gì bắt bạn phải đập TOÀN BỘ mảng xuống sheet ***. Bạn có thể "hạn chế" vùng nhận kết quả từ mảng. Nếu bạn viết
Mã:
.Worksheets("1").Range("C3").Resize(1, UBound(Arr, 1)).Value = Arr
thì điều đó được hiểu là: đập mảng Arr có 1 CỘT 11 HÀNG xuống sheet bắt đầu từ C3, nhưng "hạn chế" vùng nhận kết quả thành vùng có 1 HÀNG và 11 CỘT (UBound(Arr, 1) = 11 nên .Worksheets("1").Range("C3").Resize(1, UBound(Arr, 1)) là vùng có 1 HÀNG và 11 CỘT). Do vùng nhận chỉ có 1 HÀNG nên phần tử ở HÀNG 1 (tất nhiên ở cột 1 vì mảng chỉ có 1 cột) của Arr là "b" được "đập" xuống sheet. Do Arr chỉ có 1 cột mà vùng nhận (C3:M3) lại có 11 cột nên giá trị "b" được "đập" xuống trong 11 cột C:M - sao y bản chính "b" thành 11 bản sao để nhập vào C3:M3

Tương tự
Mã:
.Worksheets("1").Range("C5").Resize(3, UBound(Arr, 1)).Value = Arr

Vùng nhận là C5:M7. Do vùng nhận có 3 HÀNG nên 3 HÀNG đầu (tất nhiên ở cột 1 vì mảng chỉ có 1 cột) của Arr là "b", "c", "d" được "đập" xuống sheet. Do Arr chỉ có 1 cột mà vùng nhận (C5:M7) lại có 11 cột nên giá trị "b", "c", "d" được "đập" xuống trong 11 cột C:M - sao y bản chính "b", "c", "d" thành 11 bản sao để nhập vào C:M.

Tương tự với .Worksheets("1").Range("C9").Resize(4, UBound(Arr, 1)).Value = Arr
----------
Arr là mảng 2 CHIỀU chỉ có 1 CỘT nên theo bài #9
- mảng 2 CHIỀU có 1 CỘT (số HÀNG tùy ý) vd. arr(1 To 3, 1 To 1), arr(1 To 1, 1 To 1) -> Transpose trả về mảng 1 CHIỀU

thì Application.Transpose(Arr) trả về mảng 1 CHIỀU - mảng này có 11 phần tử.

Mảng 1 CHIỀU nếu đập xuống sheet toàn bộ thì phải đập xuống vùng có 1 HÀNG và nhiều cột. Vậy đập thế này
Mã:
.Worksheets("1").Range("C15").Resize(1, UBound(Arr, 1)).Value = Application.Transpose(Arr)
là đập TOÀN BỘ mảng Arr xuống sheet.

Còn cách đập
Mã:
.Worksheets("1").Range("C17").Resize(2, UBound(Arr, 1)).Value = Application.Transpose(Arr())
thì sao?
Do .Worksheets("1").Range("C17").Resize(2, UBound(Arr, 1)) là vùng có tận 2 HÀNG nên tương tự như ở trên HÀNG 1 của vùng đã được sao y để đập vào HÀNG 2 của vùng. Chả nhẽ lấy từ trên trời?

Tương tự với
Mã:
.Worksheets("1").Range("C20").Resize(3, UBound(Arr, 1)).Value = Application.Transpose(Arr())
thì kết quả HÀNG 1 được sao y 2 lần để đập vào 2 HÀNG tiếp theo.
-----------------
Ang là vùng 1 CỘT nên theo bài #7
- vùng 1 CỘT nhiều HÀNG -> luôn thành mảng 1 chiều.
thì Application.Transpose(Ang.Value) trả về mảng 1 CHIỀU. Nếu muốn đập TOÀN BỘ mảng 1 CHIỀU xuống sheet thì phải đập xuống 1 HÀNG (nhiều CỘT). Tức
Mã:
.Worksheets("1").Range("C25").Resize(, UBound(Arr, 1)).Value = Application.Transpose(Ang.Value)
là đập TOÀN BỘ mảng xuống sheet.

***:

Mã:
Sub hichic()
Dim Arr()
    Arr = ThisWorkbook.Worksheets("3").Range("C1:F4").Value    ' Arr có 4 dòng 4 cột
    ' đậpp toàn bộ Arr xuống sheet
    ThisWorkbook.Worksheets("3").Range("H1").Resize(UBound(Arr, 1), UBound(Arr, 2)).Value = Arr
    ' vùng nhận có ít dòng hơn - 2 dòng -> lấy tất cả các cột nhưng chỉ lấy 2 dòng đầu
    ThisWorkbook.Worksheets("3").Range("M1").Resize(2, UBound(Arr, 2)).Value = Arr
    ' vùng nhận có ít cột hơn - 2 cột -> lấy tất cả các dòng nhưng chỉ lấy 2 cột đầu
    ThisWorkbook.Worksheets("3").Range("R1").Resize(UBound(Arr, 1), 2).Value = Arr
   
    ' vùng nhận có nhiều dòng hơn -> những dòng quá "định mức" sẽ nhận các giá trị lỗi N/A
    ThisWorkbook.Worksheets("3").Range("H6").Resize(7, UBound(Arr, 2)).Value = Arr
   
     ' vùng nhận có nhiều cột hơn -> những cột quá "định mức" sẽ nhận các giá trị lỗi N/A
    ThisWorkbook.Worksheets("3").Range("M6").Resize(UBound(Arr, 1), 7).Value = Arr
   
    ' vùng nhận có nhiều dòng và cột hơn -> những dòng và cột quá "định mức" sẽ nhận các giá trị lỗi N/A
    ThisWorkbook.Worksheets("3").Range("H14").Resize(7, 7).Value = Arr
End Sub

Việc có thể đập xuống sheet ít hàng và / hoặc ít cột hơn là mảng đang có rất tiện. Nhiều khi ta có mảng nhiều hàng và cột do còn làm nhiều việc khác nữa nhưng ta chỉ muốn đập ít hàng cột hơn xuống sheet.

2. Trong trường hợp vùng có nhiều cột và một hàng duy nhất:
...
3. Trong trường hợp vùng có m cột và n hàng

Đọc xong điểm 1 thì bạn cũng phải hiểu điểm 2 và 3.
 
Lần chỉnh sửa cuối:
Upvote 0
À còn một điều phải nói rõ. Tại sao ở bài #17 nói nếu vùng nhận lấy dư thì sao chép ... còn ở dưới nói là lấy dư thì chỗ dư là #N/A?

Nếu mảng có 1 dòng mà vùng nhận có > 1 dòng thì "sao chép" dòng 1 để đập vào các dòng tiếp theo.
Nếu mảng có 1 cột mà vùng nhận có > 1 cột thì "sao chép" cột 1 để đập vào các cột tiếp theo.

Nhưng nếu mảng có n > 1 dòng (n > 1 cột) mà vùng lấy có > n dòng (> n cột) thì dòng quá "định mức luôn có #N/A (cột quá "định mức luôn có #N/A)

Các giá trị trả về của hàm transpose trong hai trường hợp (nếu tham số là một mảng hoặc vùng ô) là mảng một chiều hoặc hai chiều thì cái đó là học thuộc chứ không chứng minh được đúng không anh ^^
Không bao giờ học thuộc. Tất cả những cái này ở thời điểm bất kỳ đều có thể kiểm nghiệm được, vậy tại sao phải học thuộc?
 
Lần chỉnh sửa cuối:
Upvote 0
Các anh có thể không quan tâm đến bài số #15 cũng được
Tôi lỡ đọc bài 15 rồi. Và vì lỡ đọc và lỡ xem hình nên cũng phải nhắc:
Mỗi khi gán mảng xuống sheet, phải xóa dữ liệu đã gán lần trước thì mới thấy kết quả đúng. Gán 1 ô mà nhìn thấy 10 ô, 17 ô có chữ b thì làm sao cảm nhận?
 
Upvote 0
Tôi lỡ đọc bài 15 rồi. Và vì lỡ đọc và lỡ xem hình nên cũng phải nhắc:
Mỗi khi gán mảng xuống sheet, phải xóa dữ liệu đã gán lần trước thì mới thấy kết quả đúng. Gán 1 ô mà nhìn thấy 10 ô, 17 ô có chữ b thì làm sao cảm nhận?
Gán hay không gán thì nguyên tắc luôn phải xóa kết quả cũ. Nhiều người trên GPE không có thói quen xóa kết quả cũ. Tôi bao giờ cũng xóa kết quả cũ rồi mới xét dữ liệu hiện hành. Nếu dữ liệu hiện hành không có thì Exit Sub, tức đã về ngay từ vòng gửi xe. Làm gì đến vòng gán dữ liệu xuống sheet. Vì thế nguyên tắc của tôi là ngay những dòng đầu là xóa kết quả cũ sau mới xét dữ liệu hiện hành. Không có dữ liệu hiện hành thì dọn đồ chơi.

Tất nhiên anh đúng hoàn toàn. Tôi chỉ góp thêm ý vì nhiều khi đọc bài của nhiều người tôi rất dị ứng với chuyện họ không xóa kết quả cũ.

Tất nhiên là tôi nói về code thực thi công việc. Chứ code nhỏ nhỏ để test thì đôi khi có thể bỏ qua cho đỡ công.
 
Lần chỉnh sửa cuối:
Upvote 0
Web KT

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

Back
Top Bottom