Các câu hỏi về mảng trong VBA (Array)

Liên hệ QC

viehoai

Thành viên gắn bó
Tham gia
22/5/09
Bài viết
2,599
Được thích
2,908
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ị
 
Nhờ các anh làm rõ thêm tại sao của em lại toàn ra số 1 vậy
Chạy code này thì biết ngay tấp lự thôi!
PHP:
Option Explicit
Sub STT2()
Dim I As Long, Arr(1 To 100) As Double
For I = 1 To 100
   Arr(I) = I
Next I
Range("A1").Resize(, 100).Value = Arr()
End Sub
 
Upvote 0
Em xin cảm ơn. Em xin trình bày ý hiểu của mình, nếu có chổ nào sai xót mọi người chỉnh giúp em hé:

Mảng Arr(1 to 100) là mảng 1 chiều do mình tạo ra vì thế nó luôn là mảng ngang. Vì vậy nếu ta muốn gán các phần tử của mảng xuống Range thì bắt buộc Range đó phải theo chiều ngang. Như ở trên có 2 cách để thực hiện việc này:
1. Là thực hiện theo cách của anh DoveandRose tức là dùng hàm Transpose để chuyển mảng ngang do mình tạo ra thành mảng dọc rồi sau đó gán các pt của mảng xuống Sheet có Range là chiều đứng.
2. Thực hiện theo cách của bạn doatmenhhon và tác giả HYến là gán luôn mảng đó xuống sheet nhưng sheet phải có Range là theo chiều ngang.

Như vầy em đã hiểu đúng bản chất của vấn đề chưa ạ.
 
Lần chỉnh sửa cuối:
Upvote 0
em xin cảm ơn. Em hiểu như vầy không biết đã đúng chưa, nếu có chổ nào sai xót mọi người chỉnh giúp em hé:
Mảng arr(1 to 100) là mảng 1 chiều do mình tạo ra vì thế nó luôn là mảng ngang. Vì thế nếu ta muốn gán các phần tử của mảng xuống range thì bắt buộc range đó phải theo chiều ngang. Như ở trên có 2 cách để thực hiện việc này:
1. Là cách của anh doveandrose tức là dùng hàm transpose để chuyển mảng ngang thành mảng dọc rồi sau đó gán xuống sheet chứa range là chiều đứng.
2. Thực hiện theo cách của bạn doatmenhhon và tác giả hyến là gán luôn mảng đó xuống sheet nhưng sheet phải chứa range là theo chiều ngang.
Như vầy đã đúng chưa ạ.
"u" "ngờ" "ung", "đờ ung đung sắc"...... Rồi +-+-+-++-+-+-++-+-+-+
 
Upvote 0
Hi hi, em hi vọng trong dấu ba chấm kia là Đúng. Nếu mà vẫn chưa đúng thật thì xin tác giả góp ý cho em với ạ...

muốn biết đúng hay không thì bạn thử là biết, muốn hỏi mình hiểu chưa, thì bạn phải giải thích tại sao nó thế, tại sao thế, còn chỉ nhắc lại việc ng ta đã làm thì là đúng thôi.
 
Upvote 0
Em xin cảm ơn. Em xin trình bày ý hiểu của mình, nếu có chổ nào sai xót mọi người chỉnh giúp em hé:

Mảng Arr(1 to 100) là mảng 1 chiều do mình tạo ra vì thế nó luôn là mảng ngang. Vì vậy nếu ta muốn gán các phần tử của mảng xuống Range thì bắt buộc Range đó phải theo chiều ngang. Như ở trên có 2 cách để thực hiện việc này:
1. Là thực hiện theo cách của anh DoveandRose tức là dùng hàm Transpose để chuyển mảng ngang do mình tạo ra thành mảng dọc rồi sau đó gán các pt của mảng xuống Sheet có Range là chiều đứng.
2. Thực hiện theo cách của bạn doatmenhhon và tác giả HYến là gán luôn mảng đó xuống sheet nhưng sheet phải có Range là theo chiều ngang.

Như vầy em đã hiểu đúng bản chất của vấn đề chưa ạ.

Chỉ đúng đến khoảng 75%. Chỗ còn lại hơi khó chứng minh.
Thật ra, hàm application.transpose tự động chuyển mảng của bạn thành 2 chiều.

muốn biết đúng hay không thì bạn thử là biết, muốn hỏi mình hiểu chưa, thì bạn phải giải thích tại sao nó thế, tại sao thế, còn chỉ nhắc lại việc ng ta đã làm thì là đúng thôi.

Bình thường thì lý luận này đúng. Nhưng riêng trường hợp này phải biết lý thuyết mới biết cách thử.
Nếu không biết lý thuyết, bạn chỉ thử đến mức làm ra kết quả hay không thôi, chứ lý do tại sao thì hơi khó nghiệm ra.
 
Upvote 0
Bình thường thì lý luận này đúng. Nhưng riêng trường hợp này phải biết lý thuyết mới biết cách thử.
Nếu không biết lý thuyết, bạn chỉ thử đến mức làm ra kết quả hay không thôi, chứ lý do tại sao thì hơi khó nghiệm ra.

Không nghiệm ra thì là chưa hiểu, vì thế mới nói bạn ta là cần phải nói tại sao, thì mới người mới hiểu là bạn ta hiểu hay chưa. Còn suốt ngày nói chung, nói chung thế này thì biết còn cụ thể thì tắc tịt thì là chưa hiểu.
 
Upvote 0
Em xin cảm ơn. Em xin trình bày ý hiểu của mình, nếu có chổ nào sai xót mọi người chỉnh giúp em hé:

Mảng Arr(1 to 100) là mảng 1 chiều do mình tạo ra vì thế nó luôn là mảng ngang
Mảng một chiều là 1 vector mà vector thì có thể nằm đứng, nằm ngang hay nằm gì gì đó tùy ý, miễn sao là thẳng đường. do trong excel người ta quy ước sẳn khi dán mảng một chiều xuống range thì nó nằm ngang, chứ không phải mảng một chiều là mảng ngang
 
Upvote 0
Em có 2 câu hỏi nhờ mọi người tư vấn giùm ạ:
1. Vẫn là bài tập bên trên nhưng giờ em chuyển qua mảng 2 chiều (CODE này em lấy trên diễn đàn) viết như sau:
PHP:
Sub STT1()  Dim i As Long, Arr()  
ReDim Arr(1 To 100, 1 To 1)  
For i = 1 To 100   
  Arr(i, 1) = i  
Next  
Range("A1:A100").Value = Arr
End Sub
Sau khi đọc xong em sửa lại theo ý của em thành thế này :
PHP:
Sub STT2()  Dim i As Long, Arr(1 To 100, 1 To 1) 
 For i = 1 To 100    
   Arr(i, 1) = i  
 Next  
Range("A1:A100").Value = Arr
End Sub
thấy CODE vẫn chạy mà không có gì thay đổi. Vậy xin mọi người cho em hỏi giữa 2 đoạn CODE trên có điểm gì khác nhau ạ.

2.Tại sao CODE đầu tiên lại phải thên Redim vào làm gì vậy. Em có đọc và thấy mọi người nói là Redim dùng khi kích thước của mảng bị thay đổi nhưng với bài này em chưa hiểu được công dụng của nó : tức là trong TH này thì tại sao kích thước của mảng lại bị thay đổi (em có thấy bị thay đổi gì đâu) và nếu nó có thay đổi đi chăng nữa thì cũng phải qua 1 số bước bên dưới nữa thì mới bị thay đổi chớ ...sao chưa gì đã Redim ngay từ đầu CODE là vì sao vậy.
Em xin cảm ơn ạ !
 
Lần chỉnh sửa cuối:
Upvote 0
Em có 2 câu hỏi nhờ mọi người tư vấn giùm ạ:
1. Vẫn là bài tập bên trên nhưng giờ em chuyển qua mảng 2 chiều (CODE này em lấy trên diễn đàn) viết như sau:
PHP:
Sub STT1()  Dim i As Long, Arr()  
ReDim Arr(1 To 100, 1 To 1)  
For i = 1 To 100   
  Arr(i, 1) = i  
Next  
Range("A1:A100").Value = Arr
End Sub
Sau khi đọc xong em sửa lại theo ý của em thành thế này :
PHP:
Sub STT2()  Dim i As Long, Arr(1 To 100, 1 To 1) 
 For i = 1 To 100    
   Arr(i, 1) = i  
 Next  
Range("A1:A100").Value = Arr
End Sub
thấy CODE vẫn chạy mà không có gì thay đổi. Vậy xin mọi người cho em hỏi giữa 2 đoạn CODE trên có điểm gì khác nhau ạ.

2.Tại sao CODE đầu tiên lại phải thên Redim vào làm gì vậy. Em có đọc và thấy mọi người nói là Redim dùng khi kích thước của mảng bị thay đổi nhưng với bài này em chưa hiểu được công dụng của nó : tức là trong TH này thì tại sao kích thước của mảng lại bị thay đổi (em có thấy bị thay đổi gì đâu) và nếu nó có thay đổi đi chăng nữa thì cũng phải qua 1 số bước bên dưới nữa thì mới bị thay đổi chớ ...sao chưa gì đã Redim ngay từ đầu CODE là vì sao vậy.
Em xin cảm ơn ạ !

thì lúc đâu bạn chỉ khai báo nó là mảng thôi, bạn có cho nó kích thướt là bao nhiêu đâu
Mã:
dim Arr()

vậy thì bước tiếp theo bạn phải khai báo nó
Mã:
[COLOR=#000000][COLOR=#0000BB]ReDim Arr[/COLOR][COLOR=#007700]([/COLOR][COLOR=#0000BB]1 To 100[/COLOR][COLOR=#007700], [/COLOR][COLOR=#0000BB]1 To 1[/COLOR][COLOR=#007700])

chứ ngay từ đâu bạn khai báo nó vậy luôn đi
Mã:
dim [COLOR=#000000][COLOR=#0000BB]Arr[/COLOR][COLOR=#007700]([/COLOR][COLOR=#0000BB]1 To 100[/COLOR][COLOR=#007700], [/COLOR][COLOR=#0000BB]1 To 1[/COLOR][COLOR=#007700])
thì có sao đâu
bạn phải khai báo kích thướt thì tiếp theo bạn mới nhét số liệu vô được chứ
[/COLOR][/COLOR][/COLOR][/COLOR]
 
Upvote 0
Tại vì cái code redim bạn lấy của ai đó chỉ dùng để ví dụ cái gì đó chứ không phải để giải thích nhiệm vụ của redim.
Nếu bạn chịu khó tìm ký hơn, sẽ thấy bài nói về Redim.

Đại khái khai báo Dim a(1 to 100, 1 to 1) là cách khai báo mảng cứng. VBA sẽ giành ra đúng 100 dòng và 1 cột trong bộ nhớ chủa nó (vì không có kiểu phần tử cho nên nó chỉ là địa chỉ variant). Việc ginahf bộ nhớ này xảy ra lúc compile, khong phải lúc chạy.
Trong khí đó, khai báo a() và sau đó Redim a(...) là cách khai báo động, thường thường Redim a(lb to ub, ...) với lb là ub là biến chứ không phải hằng như code của bạn. VBA chỉ giành ra một địa chỉ cho a, đến khi code chạy đến chỗ redim mới biết mảng cần như thế nào và giành ra một khoảng bộ nhớ.
Không cần phải lý luận nhiều, ai cũng có thể thấy rằng cách đông linh hoạt hơn cách cứng, nhưng ngược lại, cách cứng nhanh hơn cách động.
 
Upvote 0
Như vậy là với bài tập trên của em ta không nhất thiết phải sử dụng Redim . Tuy nhiên em vẫn chưa thấy được tầm quan trọng của nó. Bây giờ mọi người có thể cho em 1 ví dụ nào đơn giản mà bắt buộc phải dùng đến Redim được không ạ để em thực sự thấy được sự cần thiết -phải có nó
 
Upvote 0
Như vậy là với bài tập trên của em ta không nhất thiết phải sử dụng Redim . Tuy nhiên em vẫn chưa thấy được tầm quan trọng của nó. Bây giờ mọi người có thể cho em 1 ví dụ nào đơn giản mà bắt buộc phải dùng đến Redim được không ạ để em thực sự thấy được sự cần thiết -phải có nó

Ví dụ:
ReDim arr(1 to n)
Với n là một biến mà bằng cách nào đó bạn phải tính toán mới có được (chẳng hạn n = rng.Rows.Count)
Vậy theo nguyên tắc thì bạn không thể Dim arr(1 to n) được mà BUỘC phải ReDim
Bởi quy định:
- Nếu n là con số "chết" cụ thể nào đó, chẳng hạn là 100 thì bạn được quyền Dim arr(1 to 100)
- Nếu n là biến mà bạn cố tình Dim arr(1 to n) thì Excel sẽ báo lỗi ngay lập tức
Anh Bill nói vậy!
 
Upvote 0
Ví dụ đơn giản:
Tôi cần một mảng để chứa n trị integer. Tôi chưa biết n là bao nhiêu.
Tôi có 2 cách code:
1. Mảng tĩnh: Tôi khai báo một mảng rất lớn - để chắc ăn là số phần tử nhiều hơn n. Và tôi phải luôn ghi nhớ rằng những phần tử sau n không dùng đến.
2. Mảng động: tôi khai báo tên mảng. Cần đến bao nhiêu, tôi lại redim đến đó.

Nhắc lại bài trước đây:
Dim a(1 to 100) là mảng tĩnh. Khai báo xong là xài được rồi. Kích cỡ (100 phần tử) và hình dáng (mảng 1 chiều) đã được cố định.
Dim a() là mảng động, chỉ có cái tên chứ chưa xài được. Chỉ sau khi Redim(...) thì mảng mới có thực chất. Lúc Redim là lúc bạn cho nó kích cỡ và hình dáng.

Chú thêm:
Dim là lệnh khai báo. Bạn dùng nó để khai báo cho trình dịch VBA biết rằng bạn sẽ sử dụng một biến như thế. Lúc khai báo bạn có quyền chọn là tĩnh hay động.
Redim là lệnh thi hành. Bạn dùng nó để ra lệnh VBA chuyển kích cỡ và hình dạng của mảng như bạn cần. Dĩ nhiên, VBA chỉ có thể chuyển dạng được mảng động.
 
Lần chỉnh sửa cuối:
Upvote 0
Nhờ các thầy/cô/anh/chị và bạn giải thích giúp em trong CODE này tại sao er lại phải cộng thêm 1 trong khi vùng dữ liệu chỉ là từ A2:F21

(trong phần chú thích CODE em có ghi rõ câu hỏi rồi đó ạ. CODE này để tính tổng cho từng bộ phận). Em xin cám ơn !
 

File đính kèm

  • mang1.xls
    45 KB · Đọc: 36
Upvote 0
Nhờ các thầy/cô/anh/chị và bạn giải thích giúp em trong CODE này tại sao er lại phải cộng thêm 1 trong khi vùng dữ liệu chỉ là từ A2:F21

(trong phần chú thích CODE em có ghi rõ câu hỏi rồi đó ạ. CODE này để tính tổng cho từng bộ phận). Em xin cám ơn !
bạn không nên hỏi tại sao er lại phải cộng thêm 1 ? vì mỗi người có 1 cách suy nghĩ khác nhau nên mỗi người có một cách viết khác nhau theo lối suy nghĩ của người ta. Bạn nên hỏi là từ đầu vào này làm sao có được đầu ra thì mọi người sẽ tư duy giúp bạn, chứ bạn hỏi như vậy, tôi cá rằng rất rất ít người đọc lại đống code của bạn rồi trả lời cho bạn, làm biếng hiểu ý của người khác lắm.
 
Upvote 0
bạn không nên hỏi tại sao er lại phải cộng thêm 1 ? vì mỗi người có 1 cách suy nghĩ khác nhau nên mỗi người có một cách viết khác nhau theo lối suy nghĩ của người ta. Bạn nên hỏi là từ đầu vào này làm sao có được đầu ra thì mọi người sẽ tư duy giúp bạn, chứ bạn hỏi như vậy, tôi cá rằng rất rất ít người đọc lại đống code của bạn rồi trả lời cho bạn, làm biếng hiểu ý của người khác lắm.

Em cũng không biết phải diễn đạt bằng cách nào để mọi người dễ hiểu hơn nữa. Tuy nhiên để hiểu đc thắc mắc của em cũng không cần phải đọc hết CODE đâu anh. Dễ hiểu lắm mà anh. Vùng chứa dữ liệu chỉ là từ A2:F21 thôi thế mà trong đoạn CODE er đã bằng 21 rồi tại sao lại phải cộng thêm 1 thế hóa ra mảng arr1 gồm các giá trị trong vùng A2:F22 --->bị thừa ra 1 dòng là sao ạ ??? Mong anh và mọi người hiểu đc khúc mắc của em và giải thích dùm em với...
 
Lần chỉnh sửa cuối:
Upvote 0
Em cũng không biết phải diễn đạt bằng cách nào để mọi người dễ hiểu hơn nữa. Tuy nhiên để hiểu đc thắc mắc của em cũng không cần phải đọc hết CODE đâu anh. Dễ hiểu lắm mà anh. Vùng chứa dữ liệu chỉ là từ A2:F21 thôi thế mà trong đoạn CODE er đã bằng 21 rồi tại sao lại phải cộng thêm 1 thế hóa ra mảng arr1 gồm các giá trị trong vùng A2:F22 --->bị thừa ra 1 dòng là sao ạ ??? Mong anh và mọi người hiểu đc khúc mắc của em và giải thích dùm em với...

thử lại er+1 thành er+0 xem có sao không, khôgn sao cả, nên đó lệnh viết thừa

Nhưng toàn bộ code đó có thể bỏ đi, vì excel có chức năng subtotal rồi: Data / subtotal...
 
Upvote 0
Em cũng không biết phải diễn đạt bằng cách nào để mọi người dễ hiểu hơn nữa. Tuy nhiên để hiểu đc thắc mắc của em cũng không cần phải đọc hết CODE đâu anh. Dễ hiểu lắm mà anh. Vùng chứa dữ liệu chỉ là từ A2:F21 thôi thế mà trong đoạn CODE er đã bằng 21 rồi tại sao lại phải cộng thêm 1 thế hóa ra mảng arr1 gồm các giá trị trong vùng A2:F22 --->bị thừa ra 1 dòng là sao ạ ??? Mong anh và mọi người hiểu đc khúc mắc của em và giải thích dùm em với...

à mấy cái này cứ để chuyên gia ba xàm trả lời nè
là vì có dòng này
Mã:
If arr1(i, 4) <> arr1(i + 1, 4) Then
đây không phải là chuyện thích hay không thích mà là với cách viết IF như này thì bắt buộc phải lấy dư 1 dòng
bạn xóa thử +1 chỗ er + 1 thử xem sao ?
 
Upvote 0
Web KT

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

Back
Top Bottom