pham van an
Thành viên mới
- Tham gia
- 22/4/09
- Bài viết
- 45
- Được thích
- 22
- Nghề nghiệp
- Giảng viên Xây dựng
Nếu viết code thì dùng Array mới cho tốc độ nhanh được!em đang có mấy cột dữ liệu ở các cột. Bây giờ em muốn chuyển các phần dữ liệu o mỗi cột lên dòng đầu tiên của cột (hoặc bất kỳ). Như F1,G1,H1. Em dùng code xóa ô trống nhưng nó lọc chậm quá. Mong các bác giúp em.
Function RemoveBlanks(ByVal SrcRng As Range)
Dim TmpArr, Arr(), Tmp() As Long, i As Long, j As Long
TmpArr = SrcRng.Value
ReDim Tmp(1 To UBound(TmpArr, 2))
ReDim Arr(1 To UBound(TmpArr, 1), 1 To UBound(TmpArr, 2))
For j = 1 To UBound(TmpArr, 2)
For i = 1 To UBound(TmpArr, 1)
If TmpArr(i, j) <> "" Then
Tmp(j) = Tmp(j) + 1
Arr(Tmp(j), j) = TmpArr(i, j)
End If
Next i
Next j
RemoveBlanks = Arr
End Function
Sub Main()
Dim SrcRng As Range, Arr
Set SrcRng = Sheet1.Range("B3:D18")
Arr = RemoveBlanks(SrcRng)
Sheet1.Range("J1").Resize(UBound(Arr, 1), UBound(Arr, 2)).Value = Arr
End Sub
Thêm một cáchem đang có mấy cột dữ liệu ở các cột. Bây giờ em muốn chuyển các phần dữ liệu o mỗi cột lên dòng đầu tiên của cột (hoặc bất kỳ). Như F1,G1,H1. Em dùng code xóa ô trống nhưng nó lọc chậm quá. Mong các bác giúp em.
Public Sub GomGom()
Dim iCot, Mg(), I, J, K
[f1].CurrentRegion.ClearContents
For I = 2 To 4
iCot = Range(Cells(1, I), Cells(10000, I).End(xlUp)).Value
ReDim Mg(1 To UBound(iCot), 1 To 1)
For J = 1 To UBound(iCot)
If iCot(J, 1) <> vbNullString Then
K = K + 1
Mg(K, 1) = iCot(J, 1)
End If
Next J
[d1].Offset(, I).Resize(K) = Mg
Mg = [w1].Resize(K).Value
K = 0
Next I
End Sub
Có thể là như thế nàyem gửi lại file excel. nhờ các bác giúp em
Link: http://www.mediafire.com/?u3608towx6qrboo
Anh concogia cho em hỏi đoạn Mg=[W1].resize(k).value có tác dụng gì. Em thấy nếu bỏ đoạn đó đoạn code vẫn chạy rất OK, Mà em thấy cũng lạ là khi anh khai báo biến không bao giờ khai báo kiểu dữ liệu mà chạy vẫn đúng!!!Thêm một cách
Mã:Public Sub GomGom() Dim iCot, Mg(), I, J, K Mg = [w1].Resize(K).Value Next I End Sub
Híc, lại bị bạn bắt giò nữa rồiAnh concogia cho em hỏi đoạn Mg=[W1].resize(k).value có tác dụng gì. Em thấy nếu bỏ đoạn đó đoạn code vẫn chạy rất OK, Mà em thấy cũng lạ là khi anh khai báo biến không bao giờ khai báo kiểu dữ liệu mà chạy vẫn đúng!!!
To Ndu: Em thích nhất là hàm Removeblanks đó cái đó, em mới biết mình có thể đặt vào Function được. Thanks Ndu
Em, đâu dám đâu tại vì em đang học về array nên mới thấy lạ hỏi anh thôi cảm ơn anh giải thíchHíc, lại bị bạn bắt giò nữa rồi
- Đơn giản vì mình cho kết quả chạy qua 3 cột mà chỉ gán bằng 1 mảng nên khi gán xong một cột mình muốn hủy mảng đó đi cho "chắc cú", bi giờ xem lại mới thấy chỉ cần gán biến K=0 là Ok rồi (dù sao cũng tìm được cách hủy mảng mà không dùng vòng lặp, lúc trước cứ phải "pho pho" hoài mới hủy được nó, bực lắm)
Thân
Thì em đọc mấy bài của bác SA_QC, thấy PTM thì khuyên nên khai báo biến thì đoạn code sẽ cho tốc độ cao hơn, mà anh khai báo biến thì nó vẫn hiểu theo kiểu là Variant, nếu người mới như em thì đọc không hiểu dẫn đến hơi mơ mơ về kiều dữ liệu, nhằm khi thấy những đoạn code của các anh chị khác viết có khai báo, còn nhằm đoạn thì khôngthì học cũng khó- Không khai báo kiểu dữ liệu cho biến thì không có vẻ "trường lớp" lắm nhưng được cái lợi là yên tâm về kết quả của nó, không khai báo kiểu dữ liệu, biến sẽ có kiểu Variant - kiểu của các kiểu dữ liệu - VBA sẽ tự động chuyển đổi kiểu dữ liệu cho phù hợp trong quá trình tính toán - "Phẻ re"
Có thể vì lẽ này, nếu ta không khai báo có nhiều trường hợp code sẽ chạy mất nhiều thời gian hơn khai báo "đàng hoàng" ( những code cần "đua" tốc độ mình đều khai báo kiểu dữ liệu của biến đầy đủ )
Thân
Em thấy anh Concogia viết code quá trùm đó mà. Thanks anh Concogia đã giải thích mong gặp anh trong sinh nhật GPEMình cũng mới biết viết code thôi, đang trong quá trình tìm hiểu & đây cũng là suy nghĩ riêng của mình
Học kiểu "giang hồ" không trường lớp khổ thế đấy
Thân
Sub Loc1()
Dim cell As Range, Rng As Range
Dim I, J As Integer
[F1].CurrentRegion.ClearContents
For I = 2 To 4
Set Rng = Range(Cells(1, I), Cells(10000, I).End(xlUp))
For Each cell In Rng.SpecialCells(2)
J = J + 1
Cells(J, I + 4).Value = cell.Value
Next
J = 0
Next I
End Sub
Sub Loc2()
Dim I As Integer
Dim Rng As Range
[F1].CurrentRegion.ClearContents
For I = 2 To 4
Set Rng = Range(Cells(1, I), Cells(10000, I).End(xlUp))
Rng.SpecialCells(2).Copy Cells(1, I + 4)
Next I
End Sub
Code của bạn dùng SpecialCells nên cần phải bẫy lỗi trong trường hợp không có dữ liệu.Giải pháp của thầy ndu cao cấp quá, cần có thời gian để tiếp thu.
Code của anh concogia thì quá OK rồi. Học được thêm 1 cách xử lý dữ liệu.
Đâu đó trên diễn đàn thỉnh thoảng lại bắt gặp anh concogia có nhiều chiêu rất hay.
Có điều riêng với yêu cầu như bài này vẫn có thể rút gọn code của concogia cho đơn giản thêm chút nữa:
Hoặc gọn hơn nữa:PHP:Sub Loc1() Dim cell As Range, Rng As Range Dim I, J As Integer [F1].CurrentRegion.ClearContents For I = 2 To 4 Set Rng = Range(Cells(1, I), Cells(10000, I).End(xlUp)) For Each cell In Rng.SpecialCells(2) J = J + 1 Cells(J, I + 4).Value = cell.Value Next J = 0 Next I End Sub
PHP:Sub Loc2() Dim I As Integer Dim Rng As Range [F1].CurrentRegion.ClearContents For I = 2 To 4 Set Rng = Range(Cells(1, I), Cells(10000, I).End(xlUp)) Rng.SpecialCells(2).Copy Cells(1, I + 4) Next I End Sub
Thấy bạn chịu khó nghiên cứu Array, tôi tặng bạn hàm mới dùng được trên vùng dữ liệu không liên tụcTo Ndu: Em thích nhất là hàm Removeblanks đó cái đó, em mới biết mình có thể đặt vào Function được. Thanks Ndu
Function RemoveBlanks(ParamArray sArray())
Dim Arr(), SubArr, Item, Tmp, lR As Long, lC As Long, lRs As Long, lCs As Long
On Error GoTo ExitFunc
For Each SubArr In sArray
Tmp = SubArr
If lRs < UBound(Tmp, 1) Then lRs = UBound(Tmp, 1)
lCs = lCs + 1
Next
ReDim Arr(1 To lRs, 1 To lCs)
For Each SubArr In sArray
lR = 0: lC = lC + 1: Tmp = SubArr
For Each Item In Tmp
If CStr(Item) <> "" Then
lR = lR + 1
Arr(lR, lC) = Item
End If
Next
Next
RemoveBlanks = Arr
ExitFunc:
End Function
Sub Main()
Dim SrcRng As Range, Arr, TG As Double
TG = Timer
On Error GoTo ExitSub
With Sheet1
.Range("AO4:AS60000").Clear
Arr = RemoveBlanks(.Range("T4:T60000"), .Range("X4:X60000"), .Range("AB4:AB60000"), .Range("AF4:AF60000"), .Range("AJ4:AJ60000"))
.Range("AO4:AS4").Resize(UBound(Arr, 1)).Value = Arr
End With
ExitSub:
MsgBox Timer - TG
End Sub