Sửa lại code của bạn.Chào các bác. Các bác bổ xung cho em thêm code để điền ô ngày tháng ở sheets"Main" giống trong sheet "Tổng hợp" với
Ngày tháng này lấy ở ô A7 của các sheets cần gộp.
Public Sub GPE()
Dim sArr(), dArr(1 To 65000, 1 To 250), I As Long, J As Long, K As Long, Col As Long, Ws As Worksheet
For Each Ws In ThisWorkbook.Worksheets
If Ws.Name <> "Main" And Ws.Name <> "Tong hop" Then
sArr = Ws.Range("A17:A" & Ws.[B65000].End(xlUp).Row).Resize(, Ws.[L17].End(xlToLeft).Column)
If Ws.[L17].End(xlToLeft).Column > Col Then Col = Ws.[L17].End(xlToLeft).Column
For I = 1 To UBound(sArr, 1)
K = K + 1
dArr(K, 1) = Ws.Range("A7")
For J = 2 To UBound(sArr, 2)
dArr(K, J) = sArr(I, J)
Next J
Next I
End If
Next
With Sheets("MAIN")
.[A4:IV65000].ClearContents
If K Then .[A4].Resize(K, Col).Value = dArr
End With
End Sub
Cảm ơn anh nhiều nha.Sửa lại code của bạn.
Bạn đổi tên Sheets("Tổng hợp") thành "Tong hop" rồi chạy code nhé!
PHP:Public Sub GPE() Dim sArr(), dArr(1 To 65000, 1 To 250), I As Long, J As Long, K As Long, Col As Long, Ws As Worksheet For Each Ws In ThisWorkbook.Worksheets If Ws.Name <> "Main" And Ws.Name <> "Tong hop" Then sArr = Ws.Range("A17:A" & Ws.[B65000].End(xlUp).Row).Resize(, Ws.[L17].End(xlToLeft).Column) If Ws.[L17].End(xlToLeft).Column > Col Then Col = Ws.[L17].End(xlToLeft).Column For I = 1 To UBound(sArr, 1) K = K + 1 dArr(K, 1) = Ws.Range("A7") For J = 2 To UBound(sArr, 2) dArr(K, J) = sArr(I, J) Next J Next I End If Next With Sheets("MAIN") .[A4:IV65000].ClearContents If K Then .[A4].Resize(K, Col).Value = dArr End With End Sub
Chào anh.Sửa lại code của bạn.
Bạn đổi tên Sheets("Tổng hợp") thành "Tong hop" rồi chạy code nhé!
PHP:Public Sub GPE() Dim sArr(), dArr(1 To 65000, 1 To 250), I As Long, J As Long, K As Long, Col As Long, Ws As Worksheet For Each Ws In ThisWorkbook.Worksheets If Ws.Name <> "Main" And Ws.Name <> "Tong hop" Then sArr = Ws.Range("A17:A" & Ws.[B65000].End(xlUp).Row).Resize(, Ws.[L17].End(xlToLeft).Column) If Ws.[L17].End(xlToLeft).Column > Col Then Col = Ws.[L17].End(xlToLeft).Column For I = 1 To UBound(sArr, 1) K = K + 1 dArr(K, 1) = Ws.Range("A7") For J = 2 To UBound(sArr, 2) dArr(K, J) = sArr(I, J) Next J Next I End If Next With Sheets("MAIN") .[A4:IV65000].ClearContents If K Then .[A4].Resize(K, Col).Value = dArr End With End Sub
Gửi lại bạn.Cảm ơn anh nhiều nha.
Bài đã được tự động gộp:
Chào anh.
Anh có thể add thêm tên sheets vào thêm một cột nữa được không ạ?
Public Sub GPE()
Dim sArr(), dArr(1 To 65000, 1 To 250), I As Long, J As Long, K As Long, Col As Long, Ws As Worksheet
For Each Ws In ThisWorkbook.Worksheets
If Ws.Name <> "Main" And Ws.Name <> "Tong hop" Then
sArr = Ws.Range("A17:A" & Ws.[B65000].End(xlUp).Row).Resize(, Ws.[L17].End(xlToLeft).Column)
If Ws.[L17].End(xlToLeft).Column > Col Then Col = Ws.[L17].End(xlToLeft).Column
For I = 1 To UBound(sArr, 1)
K = K + 1
dArr(K, 1) = Ws.Range("A7")
For J = 2 To UBound(sArr, 2)
dArr(K, J) = sArr(I, J)
Next J
dArr(K, Col + 1) = Ws.Name
Next I
End If
Next
With Sheets("MAIN")
.[A4:IV65000].ClearContents
If K Then .[A4].Resize(K, Col + 1).Value = dArr
End With
End Sub
Gửi lại bạn.
Thêm cột tên sheets vào cuối cùng.
PHP:Public Sub GPE() Dim sArr(), dArr(1 To 65000, 1 To 250), I As Long, J As Long, K As Long, Col As Long, Ws As Worksheet For Each Ws In ThisWorkbook.Worksheets If Ws.Name <> "Main" And Ws.Name <> "Tong hop" Then sArr = Ws.Range("A17:A" & Ws.[B65000].End(xlUp).Row).Resize(, Ws.[L17].End(xlToLeft).Column) If Ws.[L17].End(xlToLeft).Column > Col Then Col = Ws.[L17].End(xlToLeft).Column For I = 1 To UBound(sArr, 1) K = K + 1 dArr(K, 1) = Ws.Range("A7") For J = 2 To UBound(sArr, 2) dArr(K, J) = sArr(I, J) Next J dArr(K, Col + 1) = Ws.Name Next I End If Next With Sheets("MAIN") .[A4:IV65000].ClearContents If K Then .[A4].Resize(K, Col + 1).Value = dArr End With End Sub
Gửi bạn Oanh Thơ,Xin chào @vanthinh3101
Bạn có thể thay thế cái phần dArr(1 To 65000, 1 To 250) bằng cách sử dụng ReDim để Oanh Thơ học hỏi thêm được không ạ.
@Nguyễn Hoàng Oanh ThơXin chào @vanthinh3101
Bạn có thể thay thế cái phần dArr(1 To 65000, 1 To 250) bằng cách sử dụng ReDim để Oanh Thơ học hỏi thêm được không ạ.
@Nguyễn Hoàng Oanh Thơ
"Học hỏi thêm" - là hỏi thêm cái gì đó. Chỉ là số 65000 > 250 . 65000 / 250 = 260.
Muốn động thì cứ Chạy từng Sheet thôi, dArr sẽ được ReDim cho từng sheet (theo UBound(sArr))Xin chào HeSanbi,
OT muốn học hỏi xem có cách khai báo động nào mà không phải khai báo các con số cụ thể 65000 và 250 trong mảng dArr đó ạ.
Nếu cứ muốn biết cần bao nhiêu dòng thì trước tiên duyệtXin chào HeSanbi,
OT muốn học hỏi xem có cách khai báo động nào mà không phải khai báo các con số cụ thể 65000 và 250 trong mảng dArr đó ạ.
For Each Ws In ThisWorkbook.Worksheets
If Ws.Name <> "Main" And Ws.Name <> "Tong hop" Then
...
End If
Next
For Each Ws In ThisWorkbook.Worksheets
If Ws.Name <> "Main" And Ws.Name <> "Tong hop" Then
...
End If
Next
Cái bạn cần biết ở đây là.Xem cái mảng kết quả của mình dữ liệu lớn nhất có thể sảy ra.Rồi chọn con số lơn nhất đó để khai báo là được.Xin chào @vanthinh3101
Bạn có thể thay thế cái phần dArr(1 To 65000, 1 To 250) bằng cách sử dụng ReDim để Oanh Thơ học hỏi thêm được không ạ.
Nếu cứ muốn biết cần bao nhiêu dòng thì trước tiên duyệt
Chỗ ... thì xác định dòng cuối của sheet hiện hành. Biết dòng đầu là 17 thì tính ra số dòng có dữ liệu. Rồi cộng dồn các số dòng của từng sheet thì có số dòng cần "quan tâm". Như thế trước khi vào cụmMã:For Each Ws In ThisWorkbook.Worksheets If Ws.Name <> "Main" And Ws.Name <> "Tong hop" Then ... End If Next
chính thì Redim thôi.Mã:For Each Ws In ThisWorkbook.Worksheets If Ws.Name <> "Main" And Ws.Name <> "Tong hop" Then ... End If Next
Mà chỉ lấy 7 giá trị mỗi dòng thì cần gì 1 To 250?
Cái bạn cần biết ở đây là.Xem cái mảng kết quả của mình dữ liệu lớn nhất có thể sảy ra.Rồi chọn con số lơn nhất đó để khai báo là được.
Vd.Con chào bác,
Con cũng nghĩ là ReDim ạ nhưng con vẫn lơ mơ về cái này.
Bác cho con ví dụ chi tiết cụ thể hơn khi áp dụng vào code bài #4 được không ạ.
Sub test()
Dim r As Long, c As Long, sodong As Long, Arr()
' trong truong hop cu the thi tinh toan sodong
sodong = 1234
ReDim Arr(1 To sodong, 1 To 10)
For r = 1 To UBound(Arr)
For c = 1 To UBound(Arr, 2)
Arr(r, c) = r & c
Next c
Next r
Sheet1.Range("B7").Resize(sodong, 7).Value = Arr
End Sub
For Each Ws In ThisWorkbook.Worksheets
If Ws.Name <> "Main" And Ws.Name <> "Tong hop" Then
...
End If
Next
Dim dArr()
Dim sodong As Long
...
' chỗ này đã có sodong
' tiếp theo trước khi vào "cụm" chính thì Redim
Redim dArr(1 to sodong, 1 to 7)
' cụm chính
For Each Ws In ThisWorkbook.Worksheets
If Ws.Name <> "Main" And Ws.Name <> "Tong hop" Then
...
End If
Next
Vd.
---------------------------Mã:Sub test() Dim r As Long, c As Long, sodong As Long, Arr() ' trong truong hop cu the thi tinh toan sodong sodong = 1234 ReDim Arr(1 To sodong, 1 To 10) For r = 1 To UBound(Arr) For c = 1 To UBound(Arr, 2) Arr(r, c) = r & c Next c Next r Sheet1.Range("B7").Resize(sodong, 7).Value = Arr End Sub
Sau khi duyêt
thì có số dòng cần thiết - sodongMã:For Each Ws In ThisWorkbook.Worksheets If Ws.Name <> "Main" And Ws.Name <> "Tong hop" Then ... End If Next
Thì Redim thôi, hay bạn hỏi gì?
Mã:Dim dArr() Dim sodong As Long ... ' chỗ này đã có sodong ' tiếp theo trước khi vào "cụm" chính thì Redim Redim dArr(1 to sodong, 1 to 7) ' cụm chính For Each Ws In ThisWorkbook.Worksheets If Ws.Name <> "Main" And Ws.Name <> "Tong hop" Then ... End If Next
Mà bạn có tủ sách ngay bên phía tay phải mà. Trong VBE gõ Redim ở trường trên cùng bên phải rồi chọn vd. Redim statement. Rồi đọc thôi. Nói cho cùng tôi hơn bạn chủ yếu ở chỗ tôi chịu khó đọc tài liệu thôi.
Thực ra tôi trả lời bạn thôi chứ nếu chỉ là sao chép thì cũng có thể trong "cụm" chính với mỗi sheet hiện hành thì copy luôn nó vào "TongHop". Tất nhiên vị trí paste phải cập nhật sau mỗi lần paste để lần sau paste đúng chỗ.
Bạn đừng nói với tôi là bạn không biết xác định dòng cuối có dữ liệu nhé. Vì tôi biết bạn đã từng đọc nhiều code với lastRow rồi.
Con chưa thử nhưng con nghĩ làm việc với range thì con có thể giải quyết được theo cách này nhưng con muốn học hỏi phương pháp đưa hết vào mảng xong mới chuyển xuống range.Thực ra tôi trả lời bạn thôi chứ nếu chỉ là sao chép thì cũng có thể trong "cụm" chính với mỗi sheet hiện hành thì copy luôn nó vào "TongHop". Tất nhiên vị trí paste phải cập nhật sau mỗi lần paste để lần sau paste đúng chỗ.
Bạn hiểu vậy là không đúng lắm.Khai báo ở đây là số lớn nhất có thể sảy ra với mảng đó trong mọi trường hợp.Vì nêu bạn khai báo nhỏ hơn số đó thì có trường hợp nó chạy được.Có trường hợp nó báo lỗi.Nếu trong trường hợp mà không sác định được số lớn nhất thì bạn nên khai báo lớn nhất.Dạ,sau khi đọc các chỉ dẫn của bác con đã hiểu thêm được một chút rồi ạ.
Như vậy có nghĩa là khai báo một biến sau đó tính toán gia trị cho biến đó rồi gán và gán biến này vào mảng Redim.
Vấn đề của con hỏi làm sao để tính toán vừa đủ các phần tử trong mảng dArr(1 To 65000, 1 To 250) vì con đang nghĩ rằng
con số 65000 và 250 đang là khai báo thừa ra (dư ra), còn muốn cụ thể phần tử là bao nhiêu thì cần phải tính toán.
Nếu để tính toán số dòng cuối và cột cuôí thì con biết nếu đơn giản chỉ là tính toán ngay từ đầu trước khi For thì @vanthinh3101 cũng đã tính toán được luôn mà không cần phải khai báo thừa như vậy.
Nhưng ý con muốn hỏi là có cách nào để tính toán qua 3 vòng for ở bài 4 ra kết quả số phần tử vừa đủ để gán vào mảng dArr đó ạ.
Hic có thể con chưa biết cách diễn đạt vấn đề.
Để con tìm hiểu thêm ạ.
Cách này:
Con chưa thử nhưng con nghĩ làm việc với range thì con có thể giải quyết được theo cách này nhưng con muốn học hỏi phương pháp đưa hết vào mảng xong mới chuyển xuống range.
Cảm ơn bác ạ.
Bạn hiểu vậy là không đúng lắm.Khai báo ở đây là số lớn nhất có thể sảy ra với mảng đó trong mọi trường hợp.Vì nêu bạn khai báo nhỏ hơn số đó thì có trường hợp nó chạy được.Có trường hợp nó báo lỗi.Nếu trong trường hợp mà không sác định được số lớn nhất thì bạn nên khai báo lớn nhất.
Bạn nghĩ lôgíc đi. Vòng For ngoài sẽ có số vòng bằng số sheet. Nếu sheet hiện hành hợp lệ thì đã cần phải "nhồi" dữ liệu vào dArr rồi. Nếu số dòng cần có chưa được tính trước thì dArr (khi chỉ có dArr()) đã xác định đâu để mà "nhồi" dữ liệu vào nó? Số dòng dữ liệu chỉ biết rõ khi duyệt hết các sheet. Trong trường hợp này sodong khác gì bát nước chấm sau cuộc nhậu? Bát nước chấm cần khi nhậu chứ nhậu xong rồi mới bưng nước chấm ra thì bát nước chấm đó đâu còn cần thiết?Dạ,sau khi đọc các chỉ dẫn của bác con đã hiểu thêm được một chút rồi ạ.
Như vậy có nghĩa là khai báo một biến sau đó tính toán gia trị cho biến đó rồi gán và gán biến này vào mảng Redim.
Vấn đề của con hỏi làm sao để tính toán vừa đủ các phần tử trong mảng dArr(1 To 65000, 1 To 250) vì con đang nghĩ rằng
con số 65000 và 250 đang là khai báo thừa ra (dư ra), còn muốn cụ thể phần tử là bao nhiêu thì cần phải tính toán.
Nếu để tính toán số dòng cuối và cột cuôí thì con biết nếu đơn giản chỉ là tính toán ngay từ đầu trước khi For thì @vanthinh3101 cũng đã tính toán được luôn mà không cần phải khai báo thừa như vậy.
Nhưng ý con muốn hỏi là có cách nào để tính toán qua 3 vòng for ở bài 4 ra kết quả số phần tử vừa đủ để gán vào mảng dArr đó ạ.
Hic có thể con chưa biết cách diễn đạt vấn đề.
Để con tìm hiểu thêm ạ.
Cách này:
Con chưa thử nhưng con nghĩ làm việc với range thì con có thể giải quyết được theo cách này nhưng con muốn học hỏi phương pháp đưa hết vào mảng xong mới chuyển xuống range.
Cảm ơn bác ạ.
Cảm ơn snow25, vì thế mà OT mới thắc mắc xem có cách nào có thể xác định được số lớn nhất không ạ. Nhưng bạn @vanthinh3101 cũng bảo chưa biết cách nên OT nghĩ có thể nó rất khó nên tìm hiểu sau ạ. OT nghĩ chủ đề này có hình như sai box nên đã không tiếp tục, nhưng thế nào hôm nay chủ đề này lại tiếp tục nên OT cũng muốn tiếp tục ạ![]()
Đây mượn code bài 4, và xác định theo ý tưởng batman1 (cám ơn mọi người) thì như sau:Dạ,sau khi đọc các chỉ dẫn của bác con đã hiểu thêm được một chút rồi ạ.
Như vậy có nghĩa là khai báo một biến sau đó tính toán gia trị cho biến đó rồi gán và gán biến này vào mảng Redim.
Vấn đề của con hỏi làm sao để tính toán vừa đủ các phần tử trong mảng dArr(1 To 65000, 1 To 250) vì con đang nghĩ rằng
con số 65000 và 250 đang là khai báo thừa ra (dư ra), còn muốn cụ thể phần tử là bao nhiêu thì cần phải tính toán.
Nếu để tính toán số dòng cuối và cột cuôí thì con biết nếu đơn giản chỉ là tính toán ngay từ đầu trước khi For thì @vanthinh3101 cũng đã tính toán được luôn mà không cần phải khai báo thừa như vậy.
Nhưng ý con muốn hỏi là có cách nào để tính toán qua 3 vòng for ở bài 4 ra kết quả số phần tử vừa đủ để gán vào mảng dArr đó ạ.
Hic có thể con chưa biết cách diễn đạt vấn đề.
Để con tìm hiểu thêm ạ.
Cách này:
Con chưa thử nhưng con nghĩ làm việc với range thì con có thể giải quyết được theo cách này nhưng con muốn học hỏi phương pháp đưa hết vào mảng xong mới chuyển xuống range.
Cảm ơn bác ạ.
Public Sub GPE()
Dim sArr(), dArr(), I As Long, J As Long, K As Long, Ws As Worksheet
Dim nRows As Long, nCols As Long
nCols = 7 + 1
nRows =0
For Each Ws In ThisWorkbook.Worksheets
If Ws.Name <> "Main" And Ws.Name <> "Tong hop" Then nRows = nRows + Ws.[B65000].End(xlUp).Row - 17 + 1
Next Ws
ReDim dArr(1 To nRows, 1 To nCols)
For Each Ws In ThisWorkbook.Worksheets
If Ws.Name <> "Main" And Ws.Name <> "Tong hop" Then
sArr = Ws.Range("A17:A" & Ws.[B65000].End(xlUp).Row).Resize(, 7)
For I = 1 To UBound(sArr, 1)
K = K + 1
dArr(K, 1) = Ws.Range("A7")
For J = 2 To UBound(sArr, 2)
dArr(K, J) = sArr(I, J)
Next J
dArr(K, nCols) = Ws.Name
Next I
End If
Next
With Sheets("MAIN")
.[A4:IV65000].ClearContents
If K Then .[A4].Resize(K, Col + 1).Value = dArr
End With
End Sub
Số dòng cần thiết? Có cách. Đó là niềm tin. Làm sao chưa xét hết các sheet mà biết được từng sheet có bao nhiêu dòng để tính tổng? Chỉ có bằng niềm tin.Cảm ơn snow25, vì thế mà OT mới thắc mắc xem có cách nào có thể xác định được số lớn nhất không ạ.
Sub SoDongSuDungTrongCacTrang()
Dim Sh As Worksheet, Rng As Range, sRng As Range
Dim DongSD As Long, HangDL As Long, DongCuoi As Long
For Each Sh In ThisWorkbook.Worksheets
If IsNumeric(Sh.Name) Then
DongSD = DongSD + Sh.UsedRange.Rows.Count
MsgBox DongSD, , "Cong Dòn Sô Dòng Su Dung Dên Trang: " & Sh.Name
HangDL = HangDL + Sh.[b16].CurrentRegion.Rows.Count
MsgBox HangDL, , "Cong Dòn Só Hàng Du Liêu Dén Trang: " & Sh.Name
Set sRng = Sh.Columns("A:A").Find("*", , xlFormulas, xlWhole)
If Not sRng Is Nothing Then
DongCuoi = DongCuoi + sRng.Row
MsgBox DongCuoi, , "Tông Dòng Có 'Ghi Chú' Dên Trang: '" & Sh.Name
End If
End If
Next Sh
End Sub
Dùng 1 vòng lặp cả workbook để xác định số dòng để khai báo mảng.Hơi phí.Thà khai báo lớn nhất luôn.Bác nhỉ.PHP:Sub SoDongSuDungTrongCacTrang() Dim Sh As Worksheet, Rng As Range, sRng As Range Dim DongSD As Long, HangDL As Long, DongCuoi As Long For Each Sh In ThisWorkbook.Worksheets If IsNumeric(Sh.Name) Then DongSD = DongSD + Sh.UsedRange.Rows.Count MsgBox DongSD, , "Cong Dòn Sô Dòng Su Dung Dên Trang: " & Sh.Name HangDL = HangDL + Sh.[b16].CurrentRegion.Rows.Count MsgBox HangDL, , "Cong Dòn Só Hàng Du Liêu Dén Trang: " & Sh.Name Set sRng = Sh.Columns("A:A").Find("*", , xlFormulas, xlWhole) If Not sRng Is Nothing Then DongCuoi = DongCuoi + sRng.Row MsgBox DongCuoi, , "Tông Dòng Có 'Ghi Chú' Dên Trang: '" & Sh.Name End If End If Next Sh End Sub
Thì người ta muốn thế mà.Dùng 1 vòng lặp cả workbook để xác định số dòng để khai báo mảng.Hơi phí.Thà khai báo lớn nhất luôn.Bác nhỉ.
Thì người ta muốn thế mà.
Ý người ta hỏi không cho bài này mà chỉ tò mò xem có cách không để dùng cho tương lai.
Nhưng cái này đơn giảm mà. Book có bao nhiêu sheet? Hàng ngàn sheet thì cũng chả là bao. Có tính toán gì phức tạp, lâu đâu. Nhưng cái chính là người ta muốn thế, người ta tò mò thôi.
Cảm ơn HeSanbi, nhờ bạn tiếp tục chủ đề mà OT đã hiểu được rõ hơn Redim và bản chất của mảng (trước khi gán giá trị thì cần phải có kích thước cụ thể).Còn về Redim Preserve và Erase , OT chưa tìm hiểu. Giỏi thì OT không dám nghĩ đến chỉ hi vọng làm sao đủ để vận dụng được vào nhu cầu công việc của mình thôi ạ.@Nguyễn Hoàng Oanh Thơ
Đã học thêm được Redim chưa. Phải học Luôn Redim Preserve nhé.
Lỡ rồi vận dụng luôn Erase để hoàn thành mảng. Thế là "giỏi VBA"
Mọi người hướng dẫn cho cô ấy lên đỉnh đi
Em mượn ý tưởng của bác để thực hiện.Số dòng cần thiết? Có cách. Đó là niềm tin. Làm sao chưa xét hết các sheet mà biết được từng sheet có bao nhiêu dòng để tính tổng? Chỉ có bằng niềm tin.
Còn nếu không muốn tính trước số dòng cần thiết thì chỉ còn nước Redim mảng xoay so với mảng sẽ cần khi gặp sheet hợp lệ đầu tiên -> Redim Preserve với các sheet sau -> cuối cùng thì "xoay mảng" hiện hành 90 độ để có mảng cần có. Với cách này thì ở mọi thời điểm, trừ thời điểm xét sheet hợp lệ cuối cùng, cả thánh lẫn người trần tục đều không thể biết số dòng tổng cộng sẽ là bao nhiêu.
Sub Consolidate_Data()
Dim sArr(), dArr(), Res(), Ws As Worksheet
Dim I As Long, J As Long, K As Long, lR As Long, t, x As Long
t = Timer
x = 1
For Each Ws In ThisWorkbook.Sheets
With Ws
If .Name <> "Main" And .Name <> "Tong hop" Then
lR = .Range("B" & Rows.Count).End(xlUp).Row
sArr() = .Range("A17:G" & lR).Value
If x = 1 Then
ReDim dArr(1 To UBound(sArr, 2) + 1, 1 To UBound(sArr, 1))
Else
ReDim Preserve dArr(1 To UBound(sArr, 2) + 1, 1 To (UBound(dArr, 2) + UBound(sArr, 1)))
End If
For I = 1 To UBound(sArr, 1)
K = K + 1
dArr(1, K) = .Range("A7")
For J = 2 To UBound(sArr, 2)
dArr(J, K) = sArr(I, J)
Next J
dArr(UBound(sArr, 2) + 1, K) = .Name
Next I
x = x + 1
End If
End With
Next Ws
If K Then
ReDim Res(1 To UBound(dArr, 2), 1 To UBound(dArr, 1))
For I = 1 To UBound(dArr, 2)
For J = 1 To UBound(dArr, 1)
Res(I, J) = dArr(J, I)
Next J
Next I
End If
With Sheets("Main")
.Range("A4").CurrentRegion.Offset(1).ClearContents
.Range("A4").Resize(UBound(Res, 1), UBound(Res, 2)) = Res
End With
MsgBox "Done in " & (Timer - t) & "s.", vbInformation, "GPE"
End Sub
Đùa cũng có giới hạn. Đùa đến mức này, người ta ngỡ thật thì là chơi ác.@Nguyễn Hoàng Oanh Thơ
Thì dịch nó ra tiếng Việt:
Dim : Mù mờ - VBA Array nghĩa là mảng mù mờ
Redim: Sử dụng lại mù mờ
Preserve: Bảo quản
Redim Preserve: Sử dụng lại mảng đang được bảo quản có thể tăng kích thước chiều ngang
Erase: làm rỗng
Không chừng người ta hiểu như vậy chứ không phải đùa với "Bô lảo" N_H_O_TĐùa cũng có giới hạn. Đùa đến mức này, người ta ngỡ thật thì là chơi ác.
Từ Dim không hề dính líu đến mù mờ. Nói cho đúng thì nó rất rõ rệt. Chỉ khi dùng loại mảng động (xem giải thích từ động bên dưới) thì nó đưa ra vài uyển chuyển khiến ngừoi lạm dụng sự uyển chuyển này cho rằng đó là mù mờ.
Dim là từ cũ thời thượng (thập niên 1950-60), viết tắt của từ Dimension, có nghĩa là chiều (của mảng). Tiếp đầu ngữ "re" có nghĩa là "làm/đặt lại". Suy ra redim có nghĩa là đặt lại kích cỡ và chiều của mảng.
Mảng được khai báo ở 2 dạng, mảng tĩnh và mảng động. Lúc khia báo mà cho luôn chi tiết chiều và kích cỡ thì nó là mảng tĩnh. Lúc khai báo chưa biết chi tiết thì ngừoi ta chỉ khai báo mảng động, và sau đó dùng Redim để đặt lại chi tiết.
Redim là lệnh đặt lại kích cỡ mảng. Khi được đặt lại kích cỡ, dữ liệu có sẵn trước đó coi như mất.
Redim Preserve là lệnh đặt lại kích cỡ mảng nhưng giữ lại số dữ liệu đã có trong bộ nhớ. Vì mảng là một vùng nhớ liên tục cho nên lệnh này cũng có giới hạn của nó. Đại khái là phần thay đổi phải là chiều cuối cùng của mảng (nếu mảng có 3 chiều thì chỉ chiều thứ 3 mới thay đổi được).
Erase là lệnh xoá mảng. Tuỳ theo loại mảng mà nó xoá như thế nào. Loại mảng tĩnh thì nó xoá trở về trạng thái mới nguyên như lúc mới Dim (0, trống,...). Loại mảng động thì set luôn mảng về Nothing (tức là nếu muốn dùng lại thì phải Redim lại).
Lưu ý: VBA lạm dụng từ Dim để làm lệnh khai báo biến. Nguyên thuỷ thì Dim chỉ dùng để khai báo mảng. Ngôn ngữ BASIC cổ dùng cách khai báo mặc định cho biến (A là số, A$ là chuỗi, ...).
Quan trọng: đáng lẽ bạn Oanh Thơ phải chịu khó tìm thay vì hỏi vu vơ để nghe những câu trả lời bậy bạ. Tất cả những cái này đã từng được giải thích cặn kẽ trong mục chuyên đề "mảng". Bạn batman1 cũng có giải thích rất rõ về cấu trúc và cách hoạt động theo từng chiều cũng như bộ nhớ.
@Nguyễn Hoàng Oanh Thơ
Làm sao biết 2 người trên là Bác vậy @Nguyễn Hoàng Oanh Thơ
lấy điểm của họ chia cho 10, +10 tức là 1 người 56 và một người 66
Mà quan trọng ai lớn hơn.
Chắc Ai nhiều bài viết hơn. Nhiều lượt thích chắc chắn còn "trẻ"
Theo truyền thống người Việt mình thì "bác" là tiếng gọi lịch sự. Như vậy dẫu tôi không lớn tuổi thì cũng chẳng sao. Đối với ngừoi Bắc thì "bác" dùng cả cho phụ nữ....
OT biết không phải là vì dựa vào nhiều bài viết hay là dựa vào lượt thích.
Mà dựa vào thông tin của những người mà OT tin tưởng cho biết, với lại qua các bài viết của các bác ấy OT cũng cảm nhận được ít nhiều khi viết về các kinh nghiệm đã từng trải.
Và chuyện này đối với OT cũng không có gì phải để tâm nhiều.
...
Theo truyền thống người Việt mình thì "bác" là tiếng gọi lịch sự. Như vậy dẫu tôi không lớn tuổi thì cũng chẳng sao. Đối với ngừoi Bắc thì "bác" dùng cả cho phụ nữ.
Nếu bạn dưới 30 và không phải là con út thì khả năng tôi lớn tuổi hơn bố bạn là 50%. Bác batman1 lớn hơn tôi 1 tuổi, và bác HieuCD cũng vậy.
Tôi xem Phim miền bắc nghe hay gọi Bố
Sao @Nguyễn Hoàng Oanh Thơ không gọi là Bố.
Tôi đoán là khi nào thân thiết, thường giao tiếp mới gọi "Bố" đúng không
Chứ miền Trung tôi, kêu "chú". Già quên cả tuổi mới gọi bác
Với @Nguyễn Hoàng Oanh Thơ chắc phải kêu "Thím"
Ngữ cảnh, bác ơi. Ai mà biết người ta nói cái "Phim miền bắc" đó nó là cái gì? Nó nói về vùng nào, tầng lớp nào? Khung cảnh những lúc đối thoại ấy ra sao?Nếu tôi không quên thì chị hoặc anh của bố mẹ thì là bác, còn em thì là chú/cô, cậu/mợ. Ngoài xã hội thì loại hơn tuổi bố mình thì cũng là bác, kém thì là chú. Như vậy theo tôi OT gọi bác VetMini là bác thì chuẩn.
Người dưng nhưng đã thân quen như ruột thịt thì mới gọi là bố.
Đúng rồi bác. "Chỗ tôi" thì là chú / cô nhưng "chỗ khác" thì là chú / thím.Ngữ cảnh, bác ơi. Ai mà biết người ta nói cái "Phim miền bắc" đó nó là cái gì? Nó nói về vùng nào, tầng lớp nào? Khung cảnh những lúc đối thoại ấy ra sao?
Ngại quá mình thuộc lớp sau, hơn 1 năm mới tới tuổi về vườn, làm bạn hiểu nhầm thật đắc tộiTheo truyền thống người Việt mình thì "bác" là tiếng gọi lịch sự. Như vậy dẫu tôi không lớn tuổi thì cũng chẳng sao. Đối với ngừoi Bắc thì "bác" dùng cả cho phụ nữ.
Nếu bạn dưới 30 và không phải là con út thì khả năng tôi lớn tuổi hơn bố bạn là 50%. Bác batman1 lớn hơn tôi 1 tuổi, và bác HieuCD cũng vậy.
Cách gọi này đúng của miền Bắc rồi anh.Nếu tôi không quên thì chị hoặc anh của bố mẹ thì là bác, còn em thì là chú/cô, cậu/mợ. Ngoài xã hội thì loại hơn tuổi bố mình thì cũng là bác, kém thì là chú.
Ở ngoài Bắc (ở một số vùng địa phương), nếu thân thiết có cách gọi tương tự là "u" hoặc "bầm".Ở miệt dưới người dân quê hay gọi đàn bà lớn tuổi là "má".
Tôi xin trả lời Bác @VetMini ở cái quan điểm Dim.Dim là từ cũ thời thượng (thập niên 1950-60), viết tắt của từ Dimension
Nếu Bill dùng Dimension. Thật sự tôi không thể tin điều đó là thật.Bạn không chấp nhận Dim là viết tắt của Dimension thì là chuyện của bạn.
Nhưng bạn truyền bá trên diễn đàn này Dim có nghĩa là "mù mờ" thì đó là diễn giải sai.
Bất cứ ai từng làm việc với các phiên bản BASIC đời xưa - kể cả Bill Gates hồi ông ta còn đi học - đều biết rằng ngày xưa từ khoá Dim dùng để khai biến mảng. Lúc IBM khởi xướng từ khoá DIMENSION cho FORTRAN 2 (tiền thân của IV) thì chưa có khái niệm Object.
(FORTRAN gọi phương thức là SUBROUTINE, BASIC viết tắt là Sub. Đứng nói do từ Substitute nha)
1. DIM thời BASIC xa xưa dùng để khai báo mảng: Dim mangNếu Bill dùng Dimension. Thật sự tôi không thể tin điều đó là thật.
Không ai nghĩ đến việc dùng một Danh từ với nghĩa "Kích thước không gian" để đại diện một Ngôn ngữ lập trình định nghĩa một biến. Nó hợp với Array Dimensions.
Thử: Dim Arr() - dịch: Định nghĩa kích thước mảng chưa xác định kích thước
"Có vẻ hợp, suy nghĩ lại vài giây , định nghĩa kích thước rồi sao lại chưa xác định, vô lý sao chúng tôi chấp nhận đây ông Bill"
Thử một dịch nghĩa chung nhất:
Dim - Variable Name - Type
"Định nghĩa kích thước không gian Biến đại diện cho biến là Kiểu giá trị"
"Integer, Long, LongLong, LongPtr, Object, Byte, Single, Currency, String lấy kích thước không gian đại diện để định nghĩa phải không ông Bill, Còn gì hay hơn ông hãy dạy thêm cho chúng tôi, chúng tôi còn dùng Window của ông lâu lắm lận"
Với tính chất, bản chất của của biến một tính từ nên dành cho nó.
DIM đúng là mù mờ rồi bác...1. DIM thời BASIC xa xưa dùng để khai báo mảng: Dim mang
2. DIM thời xa xưa bắt nguồn từ từ Dimension có nghĩa: kích thước, kích cỡ, độ lớn.
3. Thời nay người ta dùng DIM để khai báo mọi biến. Nên nhớ là ngôn ngữ đời sống và cả ngôn ngữ lập trình đôi khi có thay đổi. Có những từ xa xưa có một nghĩa nào đó nhưng trong ngôn ngữ hiện đại có nghĩa khác chút. Có những từ chỉ một nhóm người cụ thể trong xa xưa, nhưng thời nay nghĩa được mở rộng cho nhóm người rộng hơn.
4. DIM nên hiểu là một từ khóa dùng để khai báo biến. Thế thôi. Sao cứ phải cái gì cũng dịch ra tiếng nói hàng ngày? Thế # dùng trong #IF, hoặc thậm chí cả cụm không thể tách rời #IF, thì dịch ra tiếng Anh (tiếng nói hàng ngày) như thế nào? # chỉ là ký tự, và #IF là cụm ký tự, đâu có là câu từ gì trong tiếng nói hàng ngày để mà dịch?
DIM chỉ là một từ khóa, nó có nghĩa y như mình "nhìn thấy", "viết ra", chứ nó không là một từ nào trong ngôn ngữ nói, viết hàng ngày. Còn nếu tò mò xem tại sao lại có từ khóa DIM mà không là DOM, DUM thì lúc nó mới nói tới lịch sử trong ngôn ngữ lập trình. Rằng DIM được dùng hồi xa xưa để khai báo mảng trong BASIC. Bây giờ nó được dùng để khai báo biến nói chung. Cái này là "câu chuyện" trên bàn nhậu thôi. Còn khi học thì cứ nhớ DIM là một từ khóa dùng để khai báo biến. Người ta có thể dùng những từ khóa khác nhưng dùng DIM vì nó được dùng ngay từ thuở sơ khai. Đọc Dim a As Long thì hiểu nghĩa cả "câu" là khai báo một biến có tên là a có kiểu dữ liệu là Long. Thế thôi. Ngay trong dịch thuật người ta cũng chủ yếu là dịch nghĩa cả câu chứ không ai dịch từng từ một. Dịch từng từ một từ Anh sang Việt hay ngược lại thì nhiều khi bản dịch rất lủng củng. Dịch nghĩa cả câu thôi.
Để đáp lời Bác @batman11. DIM thời BASIC xa xưa dùng để khai báo mảng: Dim mang
2. DIM thời xa xưa bắt nguồn từ từ Dimension có nghĩa: kích thước, kích cỡ, độ lớn.
3. Thời nay người ta dùng DIM để khai báo mọi biến. Nên nhớ là ngôn ngữ đời sống và cả ngôn ngữ lập trình đôi khi có thay đổi. Có những từ xa xưa có một nghĩa nào đó nhưng trong ngôn ngữ hiện đại có nghĩa khác chút. Có những từ chỉ một nhóm người cụ thể trong xa xưa, nhưng thời nay nghĩa được mở rộng cho nhóm người rộng hơn.
4. DIM nên hiểu là một từ khóa dùng để khai báo biến. Thế thôi. Sao cứ phải cái gì cũng dịch ra tiếng nói hàng ngày? Thế # dùng trong #IF, hoặc thậm chí cả cụm không thể tách rời #IF, thì dịch ra tiếng Anh (tiếng nói hàng ngày) như thế nào? # chỉ là ký tự, và #IF là cụm ký tự, đâu có là câu từ gì trong tiếng nói hàng ngày để mà dịch?
DIM chỉ là một từ khóa, nó có nghĩa y như mình "nhìn thấy", "viết ra", chứ nó không là một từ nào trong ngôn ngữ nói, viết hàng ngày. Còn nếu tò mò xem tại sao lại có từ khóa DIM mà không là DOM, DUM thì lúc nó mới nói tới lịch sử trong ngôn ngữ lập trình. Rằng DIM được dùng hồi xa xưa để khai báo mảng trong BASIC. Bây giờ nó được dùng để khai báo biến nói chung. Cái này là "câu chuyện" trên bàn nhậu thôi. Còn khi học thì cứ nhớ DIM là một từ khóa dùng để khai báo biến. Người ta có thể dùng những từ khóa khác nhưng dùng DIM vì nó được dùng ngay từ thuở sơ khai. Đọc Dim a As Long thì hiểu nghĩa cả "câu" là khai báo một biến có tên là a có kiểu dữ liệu là Long. Thế thôi. Ngay trong dịch thuật người ta cũng chủ yếu là dịch nghĩa cả câu chứ không ai dịch từng từ một. Dịch từng từ một từ Anh sang Việt hay ngược lại thì nhiều khi bản dịch rất lủng củng. Dịch nghĩa cả câu thôi.
(vì cần dẫn chứng, xin lỗi tác giả đã copy không xin phép trước)#6 Old Pedant đã viết:As one who was writing BASIC interpreters from 1973 through 1986, I can positively affirm that indeed it is short for DIMension. Just like REM is short for REMark. (I think that's still allowed even in VB.NET, for compatibility with ancient history.)
The original Dartmouth BASIC (yes, that's where the language came from...and did you know BASIC is an acronym? Beginner's All-purpose Symbolic Instruction Code. Want to bet that the name came before the acronym? I'll take the bet and give you odds) allowed only two kinds of names: A,B,C,A1,A2,...A9,B1,B2,...B9,...Z9 were all numbers. No distinction between integers and floating point. All math was done in floating point. And then A$,B$, C$, A1$,...Z9$ were all strings. You never had to DIM a standard variable (not even sure it was legal) because the name of course implied the type. You only used DIM to create arrays, and hence you declared the DIMension of the array.
As late as the 1980s, this kind of syntax was still the standard. The variable name implied the data type. By then, most BASICs had extended the names to many characters and the number of data types by adding different extensions. e.g., Value# was a floating point number, Index% was an integer, etc. I dunno if Visual BASIC [and yes, BASIC should always be capitalized, since it is (hah!) an acronym] was the first to start allowing DIM to specify a data type, as opposed to just an array size, or not. But certainly VB is the language that made this usage of DIM the standard.
Vâng thưa Bác VietMini ạ!Nói nhiều rắc rối thật. Xem nguồn ở đây nè:
http://p2p.wrox.com/book-beginning-...ning-vb-net-2003/7654-origin-dim-keyword.html
(vì cần dẫn chứng, xin lỗi tác giả đã copy không xin phép trước)
indeed it is short for DIMension. Just like REM is short for REMark = chính thực là viết tắt từ DIMension. Cũng như REM là viết tắt từ REMark.
Càng nói càng tùm lum. Từ khóa Let vẫn còn nằm ràng ràng đó, chẳng có chuyển đi đâu cả....
Từ khóa LET mới dùng để khai báo biến. Khi chuyển giao cho Microsoft phát triển VB thì từ khóa Let đã được chuyển vào khai báo trong Class hướng đối tượng. ...
.... Khi là người Việt Nam học VBA Online , Họ dịch Google Dim vẫn là "mù mờ" / "không rõ ràng" , trong Docs của Microsoft cũng không đề cập đến Dim là viết tắc của Dimension. Mà đã chuẩn hóa là Dim "mù mờ" / "không rõ ràng" để phù hợp với hiện tại.
...
Tôi đã nói rồi. DIM từ đâu ra là để có câu chuyện trên bàn nhậu thôi.Để đáp lời Bác @batman1
Mọi Tuyên bố Hàm, Biến, ... Trong VBA hầu hết đều dịch ra nghĩa đời sống.
#IF là vì trước đây VBA chưa có định nghĩa Con trỏ thì VBA chưa có Ký tự đại diện cho Hàm Băm (Hash function) này. Con trỏ trỏ đến địa chỉ vùng nhớ ( Hệ thống ). Từ khi win64 bit ra đời, phát triển đa nền tảng cũng đi theo thời đại, định nghĩa Con trỏ với VBA cũng xuất hiện. Thì # Thể hiện là một lệnh Tiền xử lý, lệnh được xử lý trước khi biên dịch mã. # là ký tự đại diện lệnh hàm Băm.
về Dim, đơn giản nhất: tôi đọc nó là Đim , Dimension phải đọc là diˈmenCHən theo Google Translate, tiếng Việt có lẽ là Tì Men Chình.
Nếu Dim là Viết tắt của Dimension, thì tôi cần phải đọc là "Đi mờ" để tôi luôn nhớ nó là diˈmenCHən, Không thể đọc Đim nữa. Chứ không thì tôi sẽ không nhớ nổi nó là diˈmenCHən.
Và thời xa xưa Bác nói tôi tưởng tượng 500 năm trước chứ không phải BASIC 1963 theo Wikipedia, thì lúc đó Ngôn ngữ con người chưa được Chuẩn hóa như bây giờ. Chứ 1963 tới nay , tôi nghĩ ngôn ngữ không thêm mới nhiều lắm.
Và tôi không tin nổi khi phải dùng 1 từ xa xưa ấy , trong khi If, Then, While, Do, Loop, ... Hàng tá toàn là từ hiện đại.
"Phải chăng DIM đến từ hành tinh khác nên rất lợi hại"
Quả là chả cần biết DIM từ đâu ra. Chính các bài trong cái link (của O'Reily) tôi đưa ra cũng cho thấy những người biết cũng vẫn code VBA đều đặn.Tôi đã nói rồi. DIM từ đâu ra là để có câu chuyện trên bàn nhậu thôi.
Còn những người bây giờ học VB thì cần gì biết DIM từ đâu ra? Họ vẫn học được dù chả biết DIM từ đâu ra. Vì họ chỉ cần biết đó là từ khóa dùng khi khai báo biến. Và nó có ý nghĩa y như người ta "nhìn thấy", "viết ra". Kiểu như "a" có ý nghĩa là "a", "z" có nghĩa là "z".
Chính bạn mới là người cố tình dịch ra mù mờ hay không mù mờ. Tôi và bác VetMini chỉ nói về nguồn gốc của DIM mà thôi.