Hỏi cách viết VBA tạo số thứ tự

  • Thread starter Thread starter ST-Lu!
  • Ngày gửi Ngày gửi
Liên hệ QC

ST-Lu!

Love Wingchun
Tham gia
19/8/08
Bài viết
730
Được thích
546
Nghề nghiệp
Xích lô một thời
Em đang học VBA và muốn làm một việc như sau

Chọn range("b1")
Nếu A1<>"" thì b1 =1 ' A1 khác rỗng
Bắt đầu b2
Nếu A2 = "" thì b2 = 1 ---> có nghĩa là (Ai = " " --> Bi = 1 " i <>1)

Đến khi nào gặp cột Ai <> "" thì Bi = 2

Cứ thế

Exit khỏi vòng lặp khi gặp dòng text cuối cùng...(có thể xác định dòng cuối bằng Cells(Cells.Rows.Count, 1).End(xlUp).Row



Mong các anh chỉ bảo
 
Lần chỉnh sửa cuối:
Chỉ cần ba câu lệnh sau:

PHP:
Option Explicit
Sub Macro1()
    Columns("A:A").Select
    Selection.SpecialCells(xlCellTypeConstants, 23).Select
VietNam:    Selection.Offset(, 1) = 1
End Sub

Trong đó hết 2 câu nhờ bộ thu rồi!
Chú ý: con số 23, ta có thể thay số khác cho thích hợp với yêu cầu-=.,,
 
Lần chỉnh sửa cuối:
Upvote 0
Cám ơn ChănhTQ

Mình cần đánh số thứ tự mà
nếu ô bên trái (A1) khác rồng --> ô bên phải (B1) là 1
nếu ô dưới (A2...có thể là Ai) rỗng --- > B1...hay Bi cũng bằng 1 (bằng so với ở trên)

vòng lặp sẽ chạy theo Ai --> Ar (i=1)
r =Cells(Cells.Rows.Count, 1).End(xlUp).Row

nó chạy từ A1 đến khi nào gặp ô khác rỗng --> ổ bên phải B tương ứng = 2

---------------
ý mình là đánh số thứ tự đó mà
 

File đính kèm

Upvote 0
Cám ơn ChănhTQ

Mình cần đánh số thứ tự mà
nếu ô bên trái (A1) khác rồng --> ô bên phải (B1) là 1
nếu ô dưới (A2...có thể là Ai) rỗng --- > B1...hay Bi cũng bằng 1 (bằng so với ở trên)

vòng lặp sẽ chạy theo Ai --> Ar (i=1)
r =Cells(Cells.Rows.Count, 1).End(xlUp).Row

nó chạy từ A1 đến khi nào gặp ô khác rỗng --> ổ bên phải B tương ứng = 2

---------------
ý mình là đánh số thứ tự đó mà
bạn thử chạy đoạn code này xem sao nhé
PHP:
Sub Stt()
er = [a65535].End(xlUp).Row
Set rng = Range("A1:A" & er)
    k = 0
    For i = 1 To er
        If rng(i) <> "" Then
            k = k + 1
            Cells(i, 2) = k
        End If
    Next
End Sub
Hoặc là
PHP:
Sub Stt()
er = [a65535].End(xlUp).Row
Set rng = Range("A1:A" & er)
    k = 0
    For i = 1 To er
        If rng(i) <> "" Then
            k = k + 1
            Cells(i, 2) = k
        Else
            Cells(i, 2)=Cells(i-1, 2)
       End If
    Next
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Ha ha...
Em hiểu rồi, mấu chốt ở chỗ cho k = 0 (để ghi vào bộ nhớ)--
---------
Em xin hỏi tí tẹo nữa. Bác nói sơ qua về set... giúp em với

Cám ơn bác
 
Upvote 0
bạn thử chạy đoạn code này xem sao nhé
PHP:
Sub Stt()
er = [a65535].End(xlUp).Row
Set rng = Range("A1:A" & er)
    k = 0
    For i = 1 To er
        If rng(i) <> "" Then
            k = k + 1
            Cells(i, 2) = k
        End If
    Next
End Sub
Hoặc là
PHP:
Sub Stt()
er = [a65535].End(xlUp).Row
Set rng = Range("A1:A" & er)
    k = 0
    For i = 1 To er
        If rng(i) <> "" Then
            k = k + 1
            Cells(i, 2) = k
        Else
            Cells(i, 2)=Cells(i-1, 2)
       End If
    Next
End Sub
Ngắn 1 tí Boyxin ơi!
PHP:
Sub Stt()
Er = [A65535].End(xlUp).Row
Set Rng = Range("A1:A" & Er)
    For Each Clls In Rng
      k = k - (Clls <> "")
      Clls.Offset(, 1) = k
    Next
End Sub
Tin chắc vẩn còn 1 cách khác nhanh hơn rất nhiều (về tốc độ)... Nhưng với dử liệu ít ta có thể tạm chấp nhận code này
 
Lần chỉnh sửa cuối:
Upvote 0
Có bác nào am hiểu "Đệ Quy" không? Có thể áp dụng làm cái này để em học hỏi được không? Nghe mấy bác làm mà sao khó hiểu quá! Thân.
 
Lần chỉnh sửa cuối:
Upvote 0
Cám ơn ChănhTQ

Mình cần đánh số thứ tự mà
nếu ô bên trái (A1) khác rồng --> ô bên phải (B1) là 1
nếu ô dưới (A2...có thể là Ai) rỗng --- > B1...hay Bi cũng bằng 1 (bằng so với ở trên)

vòng lặp sẽ chạy theo Ai --> Ar (i=1)
r =Cells(Cells.Rows.Count, 1).End(xlUp).Row

nó chạy từ A1 đến khi nào gặp ô khác rỗng --> ổ bên phải B tương ứng = 2

---------------
ý mình là đánh số thứ tự đó mà

Tham khảo nhé : Lợi dụng hàm Excel :

PHP:
Sub STT()
    With Sheet1
        With .Range("B2:B" & .Range("A65000").End(xlUp).Row)
            .FormulaR1C1 = "=IF(RC[-1]="""",R[-1]C,R[-1]C+1)"
            .Calculate
            .Value = .Value
        End With
    End With
End Sub
Chúc vui
 
Upvote 0
Có bác nào am hiểu "Đệ Quy" không? Có thể áp dụng làm cái này để em học hỏi được không?
Nghe mấy bác làm mà sao khó hiểu quá!
Thân.
Tôi cũng đang nghiên cứu về vấn đề này nhưng chưa "thông" lắm (chắc phải nhờ các đại cao thủ)
-----------------------------------------------------
Với bài toán trên, nếu dử liệu nhiều tôi sẽ phân tích như sau:
1> Cột A có 2 loại dử liệu (tạm gọi là vậy vì tôi không biết dùng từ chính xác) : Đó là những cell có dử liệucác cell rổng
2> Nếu dùng vònglập theo cách thông thường, cột A có bao nhiêu cell thì vòng lập sẽ tốn bấy nhiêu lần quét---> Cụ thể trong file có 14 cell ==> Vòng lập tốn 14 lần duyệt
3> Nếu ta dùng phương thức SpecialCells duyệt qua các cell có dử liệu trước ---> Vị chi tốn 3 lần... Tiếp theo lại dùng phương thức SpecialCells duyệt qua các cell rổng ---> vị chi tốn 2 lần (mổi lần duyệt nguyên 1 Areas chứ không duyệt từng cell)
===> Với dử liệu trên, nếu tôi dùng SpecialCells thì chỉ tốn có 5 lần duyệt ===> Dử liệu càng lớn và số lượng cell rổng càng nhiều thì mới thấy được sự cải thiện về tốc độ...
Ví dụ: Dử liệu có 1000 dòng, trong đó có 100 cell có dử liệu và 900 cell rổng. Nếu dùng For theo cách thông thường thì tốn 1000 lần duyệt, còn như dùng SpecialCells (kết hợp thuộc tính Areas) thì tôi chỉ tốn có 100 + 99 = 199 lần duyệt ===> Tốc độ tăng ít nhất 5 lần ===> Đã không?
Các bạn thử xem!
 
Upvote 0
Đối với bài này: boyxin thì lại nghi như thế này có thể cải thiện tốc độ
PHP:
Sub Macro4()
    Range(Cells(1), [A65535].End(xlUp)).Select
    Selection.AutoFilter Field:=1, Criteria1:="<>"
    Set Rng = Selection.SpecialCells(xlCellTypeVisible)
    For Each Clls In Rng
        k = k - (Clls <> "")
        Clls.Offset(, 1) = k 
    Next
    Selection.AutoFilter
End Sub
đã test với cột A với 50 000 dòng, vẫn chạy vèo vèo
 
Lần chỉnh sửa cuối:
Upvote 0
Đối với bài này: boyxin thì lại nghi như thế này có thể cải thiện tốc độ
PHP:
Sub Macro4()
    Range(Cells(1), [A65535].End(xlUp)).Select
    Selection.AutoFilter Field:=1, Criteria1:="<>"
    Set Rng = Selection.SpecialCells(xlCellTypeVisible)
    For Each Clls In Rng
        k = k - (Clls <> "")
        Clls.Offset(, 1) = k 
    Next
    Selection.AutoFilter
End Sub
đã test với cột A với 50 000 dòng, vẫn chạy vèo vèo
Cái này là Boyxin chỉ điền STT vào các cell có dử liệu thôi, trong khi yêu cầu điền tất tần tật cơ mà...
Mà dù là điền STT vào các cell có dử liệu thì cũng đâu cần đến AutoFilter chứ
Vầy không được sao:
PHP:
Sub Test()
   Dim Rng As Range, Clls As Range, k As Long
   Set Rng = Range("A1:A" & [A65536].End(xlUp).Row).SpecialCells(2, 23)
   For Each Clls In Rng
     Clls.Offset(, 1) = k + 1: k = k + 1
    Next
End Sub
Chạy có vèo vèo không?
Ẹc... Ẹc...
---------------------
Quay trở lại vấn đề, nếu buộc phải điền STT vào tất cả thì tôi vẩn dùng bao nhiêu đó số lần quét (giống như code trên)
PHP:
Sub STT2()
  Dim Rng As Range
  Dim i As Long, k As Long
  With Range("A1:A" & [A65536].End(xlUp).Row)
     k = .SpecialCells(4).Areas.Count
     For i = 1 To k
       Set Rng = Union(.SpecialCells(2, 23).Areas(i), .SpecialCells(4).Areas(i))
       Rng.Offset(, 1).Value = i
     Next
  End With
  [A65536].End(xlUp).Offset(, 1) = k + 1
End Sub
Dù điền tất cả nhưng bảo đãm tốc độ vẩn bằng với code mà Boyxin đã nêu ở trên (chỉ điền STT ở các cell có dử liệu)
 

File đính kèm

Upvote 0
Sao dòng 65536 có dữ liệu mà code không điền STT. ndu96081631 xem chưa? vì sao nhỉ?
Ai chà... câu hỏi hay... Ẹc... Ẹc...
Cùng lắm thì bạn IF 1 cái là xong chứ gì
Chẳng hạn:
PHP:
Sub STT2()
  Dim Rng As Range, Src As Range
  Dim i As Long, k As Long
  If [A65536] = "" Then
    Set Src = Range("A1:A" & [A65536].End(xlUp).Row)
  Else
    Set Src = Range("A1:A65536")
  End If
  With Src
     k = .SpecialCells(4).Areas.Count
     For i = 1 To k
       Set Rng = Union(.SpecialCells(2, 23).Areas(i), .SpecialCells(4).Areas(i))
       Rng.Offset(, 1).Value = i
     Next
  End With
  Rng.End(xlDown).Offset(, 1) = k + 1
End Sub
Còn cách nào hay hơn nữa, các bạn cứ tiếp.... (Quan trọng vẩn là thuật toán)
 
Upvote 0
Hay quá. Cảm ơn boyxin
code của bác hay, nhưng nếu như sau khi chạy code, số TT tự đánh vào cột yêu cầu, thay vì mình ghi vào chữ số thì có thể ghi bằng công thức để khi có 1 hàng nào ở cột A bị xoá hoặc chèn thêm thì STT vẫn đúng.
Ví dụ như file này số TT động; nhưng mình không biết chạy macro.
Mong được chỉ giáo.
Thanks.
 

File đính kèm

Upvote 0
Hay quá. Cảm ơn boyxin
code của bác hay, nhưng nếu như sau khi chạy code, số TT tự đánh vào cột yêu cầu, thay vì mình ghi vào chữ số thì có thể ghi bằng công thức để khi có 1 hàng nào ở cột A bị xoá hoặc chèn thêm thì STT vẫn đúng.
Ví dụ như file này số TT động; nhưng mình không biết chạy macro.
Mong được chỉ giáo.
Thanks.

Bạn xem thế này có được không?
 

File đính kèm

Upvote 0
Cảm ơn boyxin, nhưng Bác boyxin ơi, ý mình không phải vậy. Nếu như vậy thì cũng như sau khi thay đổi mình chạy lại macro đánh STT; ý mình muốn là sau khi chạy macro thì cột STT có công thức (chỉ những hàng cột B có dữ liệu thôi nha) như trong file, như thế khi ta xoá một hàng dữ liệu cột B thì STT ở cột A thay đổi mà không phải chạy lại macro.
Mong được giúp đỡ.
Very Thanhks!
 
Upvote 0
Cảm ơn boyxin, nhưng Bác boyxin ơi, ý mình không phải vậy. Nếu như vậy thì cũng như sau khi thay đổi mình chạy lại macro đánh STT; ý mình muốn là sau khi chạy macro thì cột STT có công thức (chỉ những hàng cột B có dữ liệu thôi nha) như trong file, như thế khi ta xoá một hàng dữ liệu cột B thì STT ở cột A thay đổi mà không phải chạy lại macro.
Mong được giúp đỡ.
Very Thanhks!

Sau khi thay đổi xong mới chạy lại macro đánh STT là cách tối ưu đó bạn. Theo ý của bạn thì phải bổ sung thêm code để mỗi khi ô hiện hành tại cột B thay đổi thì tự chạy lại macro ? nhìn thì hay thôi chứ khi làm việc với bảng tính lớn thì tốc độ chậm lắm đó. Ví dụ bạn định lấy một bộ ấm chén từ phòng này sang phòng khác thay vì 1 chuyến bạn cầm cả bộ thì mối chuyến bạn chỉ cầm 1 thứ tức là bạn phải mất thời gian gấp khoảng n lần.
 
Upvote 0
Không phải vậy, mình muốn sau khi thực hiện macro công thức đánh STT cột A vẫn còn thế thôi.
 
Upvote 0
Nhưng cái này viết bằng VBA nên không có công thức, mỗi khi chạy macro là nó điền giá trị đã tính toán, còn nếu bạn muốn có công thức tại cột A thì code phải viết theo cách khác, nếu bạn cần thì mình sẽ quay lại bài này sau ít phút (đang dở kiếm bài)
 
Upvote 0
Điền công thức đánh STT

Có phải thế này không ? Trong bài đánh STT tại cột D nếu bạn muốn đánh STT ở cột nào thì sửa lại code nhé (chỉ cần sửa D = tên cột mà bạn muốn là được)
 

File đính kèm

Upvote 0
Web KT

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

Back
Top Bottom