Chuyên mục xử lý, gỡ rối code VBA (2 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

Status
Không mở trả lời sau này.

ndu96081631

Huyền thoại GPE
Thành viên BQT
Super Moderator
Tham gia
5/6/08
Bài viết
30,703
Được thích
53,957
Xin các Thầy xem giúp em có cách nào làm cho đoạn code này nó ngắn lại không ? **~**

PHP:
Private Sub CommandButton1_Click()
Dim a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z
a = Worksheets("A").Range("A1048576").End(xlUp).Row - 2
Label22.Caption = a
b = Worksheets("B").Range("A1048576").End(xlUp).Row - 2
Label23.Caption = b

End Sub

Đây là code của module UserForm?
Nếu bạn có code lặp lại kiểu đó, tức làm những việc như nhau mà chúng chỉ khác nhau "một chút nào đó" - ở đây là tên Sheet và chỉ số của Label - thì bạn phải nghĩ ngay tới vòng lặp. Chính vì thế mà ở bài 1 ta phải học các cấu trúc có trong ngôn ngữ và hiểu được triết lý của chúng. Có như vậy khi gặp vấn đề ta mới biết là cần cấu trúc nào, cấu trúc nào thích hợp nhất.

Ở đây nên dùng vòng For. Vòng lặp Do ... Loop cũng chả sao nhưng rõ ràng ta biết rất rõ có tất cả bao nhiêu vòng lặp - không ít hơn mà cũng không nhiều hơn.

Mã:
Private Sub CommandButton1_Click()
Dim index As Long, curr_row As Long, sum_row As Long
    For index = 65 To 90
        curr_row = Worksheets(Chr(index)).Range("A1048576").End(xlUp).Row - 2
        Controls("Label" & index - 43).Caption = curr_row
        sum_row = sum_row + curr_row
    Next index
    Label48.Caption = sum_row
End Sub

Về khai báo biến nếu nó luôn là Long thì khai báo là Long. Chỉ riêng về bộ nhớ thì Variant chiếm 16 bai trong khi Long chỉ chiếm 4 bai. Variant chỉ khi cần phải thế.
 
Upvote 0
Đây là code của module UserForm?
Nếu bạn có code lặp lại kiểu đó, tức làm những việc như nhau mà chúng chỉ khác nhau "một chút nào đó" - ở đây là tên Sheet và chỉ số của Label - thì bạn phải nghĩ ngay tới vòng lặp. Chính vì thế mà ở bài 1 ta phải học các cấu trúc có trong ngôn ngữ và hiểu được triết lý của chúng. Có như vậy khi gặp vấn đề ta mới biết là cần cấu trúc nào, cấu trúc nào thích hợp nhất.

Ở đây nên dùng vòng For. Vòng lặp Do ... Loop cũng chả sao nhưng rõ ràng ta biết rất rõ có tất cả bao nhiêu vòng lặp - không ít hơn mà cũng không nhiều hơn.

Mã:
Private Sub CommandButton1_Click()
Dim index As Long, curr_row As Long, sum_row As Long
    For index = 65 To 90
        curr_row = Worksheets(Chr(index)).Range("A1048576").End(xlUp).Row - 2
        Controls("Label" & index - 43).Caption = curr_row
        sum_row = sum_row + curr_row
    Next index
    Label48.Caption = sum_row
End Sub

Về khai báo biến nếu nó luôn là Long thì khai báo là Long. Chỉ riêng về bộ nhớ thì Variant chiếm 16 bai trong khi Long chỉ chiếm 4 bai. Variant chỉ khi cần phải thế.

Em cũng nghĩ đến vòng lặp For, nhưng ko biết làm sao cho nó chạy từ A tới Z -\\/.. Nhìn code của Thầy thì em hiểu là trong mã ASCII số 65 là A... hihi%#^#$. Còn về khai báo biến thì thật tình em ko biết vì em ko có học bài bản VBA mà chỉ học từ những gì cần làm và hỏi các Thầy trên forum thôi /-*+/. Cám ơn Thầy nhiều lắm @$@!^%
 
Upvote 0
Em cũng nghĩ đến vòng lặp For, nhưng ko biết làm sao cho nó chạy từ A tới Z

Thì phải "xoay xở" một tí, láu cá một tí.

Ví dụ ta gán cho những chữ cái A-Z những số tự nhiên liên tục, vd. từ 1 tới 26 hoặc k tới k+25. Gán bằng cách nào? Vd. bằng cách cho vào mảng. Lúc đó mỗi chữ cái được gán cho 1 số là chỉ số trong mảng của chữ cái đó. Tức khi duyệt các chỉ số thì ta cũng có chữ cái tương ứng.

Vd.
Mã:
Private Sub CommandButton1_Click()
Dim index As Long, curr_row As Long, sum_row As Long, Arr()
    Arr = Array("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z")
    For index = 0 To UBound(Arr)
        curr_row = Worksheets(Arr(index)).Range("A1048576").End(xlUp).Row - 2
        Controls("Label" & index + 22).Caption = curr_row
        sum_row = sum_row + curr_row
    Next index
    Label48.Caption = sum_row
End Sub

Trong trường hợp khác thì các phần tử trong mảng "kia" có thể là tên (string) các control, tên các sheet ... hoặc là đối tượng (object, vd. các Range) luôn
 
Upvote 0
Thì phải "xoay xở" một tí, láu cá một tí.

Ví dụ ta gán cho những chữ cái A-Z những số tự nhiên liên tục, vd. từ 1 tới 26 hoặc k tới k+25. Gán bằng cách nào? Vd. bằng cách cho vào mảng. Lúc đó mỗi chữ cái được gán cho 1 số là chỉ số trong mảng của chữ cái đó. Tức khi duyệt các chỉ số thì ta cũng có chữ cái tương ứng.

Vd.
Mã:
Private Sub CommandButton1_Click()
Dim index As Long, curr_row As Long, sum_row As Long, Arr()
    Arr = Array("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z")
    For index = 0 To UBound(Arr)
        curr_row = Worksheets(Arr(index)).Range("A1048576").End(xlUp).Row - 2
        Controls("Label" & index + 22).Caption = curr_row
        sum_row = sum_row + curr_row
    Next index
    Label48.Caption = sum_row
End Sub

Trong trường hợp khác thì các phần tử trong mảng "kia" có thể là tên (string) các control, tên các sheet ... hoặc là đối tượng (object, vd. các Range) luôn

_ Tuyệt vời, nếu gán bằng Mảng như thế thì mình có thể đặt tên Sheet = bất kỳ tên gì ko nhất thiết phải mang tính chất liên tục như từ A tới Z đúng ko Thầy.
_ Thầy cho em hỏi, em làm cái code tạo sheet, mà ko biết làm sao cho nó kiểm tra nếu đã có sheet đó rồi thì bỏ qua, tạo tiếp sheet tiếp theo. Thầy giúp em chỉnh cái code này lại nha :

PHP:
Private Sub CommandButton10_Click()
Dim i As Long
Dim sh As WorkSheet
For i = 65 To 90
     For Each sh In ThisWorkbook.Sheets    
            If UCase(sh.Name) = Chr(i) Then    
               Me.CommandButton10.Visible = False    
               Exit Sub    
            End If
     Next

Worksheets.Add(After:=Sheets(Sheets.Count)).Name = Chr(i)
ActiveSheet.Range("A1") = "0" & Chr(i)
ActiveSheet.Range("A2") = "0" & Chr(i)

Next

Worksheets.Add(After:=Sheets(Sheets.Count)).Name = "Number"
ActiveSheet.Range("A1") = "0A"
ActiveSheet.Range("A2") = "0A"

End Sub

_ Làm sao mình short lại thứ tự của các Sheet vậy Thầy ? vd : B - E - F - D - C - A. mình short nó lại thành A- B - C - D - E - F đó.
 
Lần chỉnh sửa cuối:
Upvote 0
_ Tuyệt vời, nếu gán bằng Mảng như thế thì mình có thể đặt tên Sheet = bất kỳ tên gì ko nhất thiết phải mang tính chất liên tục như từ A tới Z đúng ko Thầy.

Thế bạn không tự thử được à? Tự thử, mục sở thị thì mới "lên tay" được.
_ Thầy cho em hỏi, em làm cái code tạo sheet, mà ko biết làm sao cho nó kiểm tra nếu đã có sheet đó rồi thì bỏ qua, tạo tiếp sheet tiếp theo. Thầy giúp em chỉnh cái code này lại nha :

PHP:
Private Sub CommandButton10_Click()
Dim i As Long
Dim sh As WorkSheet
For i = 65 To 90
     For Each sh In ThisWorkbook.Sheets    
            If UCase(sh.Name) = Chr(i) Then    
               Me.CommandButton10.Visible = False    
               Exit Sub    
            End If
     Next

Worksheets.Add(After:=Sheets(Sheets.Count)).Name = Chr(i)
ActiveSheet.Range("A1") = "0" & Chr(i)
ActiveSheet.Range("A2") = "0" & Chr(i)

Next

Worksheets.Add(After:=Sheets(Sheets.Count)).Name = "Number"
ActiveSheet.Range("A1") = "0A"
ActiveSheet.Range("A2") = "0A"

End Sub
Mã:
Private Sub CommandButton10_Click()
Dim index As Long, sh As Worksheet, a
    For index = 65 To 90
        On Error Resume Next
        a = Sheets(Chr(index)).[A1].Value
        If Err.Number Then
            Err.Clear
            On Error GoTo 0
            Set sh = Worksheets.Add
            With sh
                .Name = Chr(index)
                .Range("A1").Value = Chr(index)
                .Range("A2").Value = Chr(index)
            End With
        End If
    Next index
    
'    SortSheets
End Sub

_ Làm sao mình short lại thứ tự của các Sheet vậy Thầy ? vd : B - E - F - D - C - A. mình short nó lại thành A- B - C - D - E - F đó.
Giả sử trong cửa sổ chính ta nhìn thấy 3 sheet theo thứ tự B, C, A và thao tác bằng tay ta kéo A lên đầu để các sheet theo thứ tự A, B, C. Bây giờ bạn muốn làm điều đó bằng code? Nếu thế thì: Alt + F11 --> Insert --> Module --> dán code sau vào Module1.
Mã:
Sub SortSheets()
Dim k As Long, n As Long
    For k = Sheets.Count To 2 Step -1
        For n = 1 To k - 1
            If [COLOR=#ff0000]Sheets(n).Name > Sheets(n + 1).Name[/COLOR] Then Sheets(n).Move After:=Sheets(n + 1)
        Next n
    Next k
End Sub

Tất nhiên code trên chỉ làm đúng ý khi vd. tên các sheet là A, B, C, ...
Nếu tên các sheet là vd. Tháng 1, Tháng 2, ..., Tháng 12 thì sau khi chạy code sẽ có thứ tự Tháng 1, Tháng 10, Tháng 11, Tháng 12, Tháng 2, Tháng 3, ..., Tháng 9.
Trong trường hợp trên thì có thể trước khi so sánh 2 chuỗi - dòng đỏ đỏ - thì biến chúng, tức 2 chuỗi so sánh chứ không phải đổi tên 2 sheet, thành dạng Tháng 01, Tháng 02, ..., Tháng 09, Tháng 10, ..., Tháng 12.

Tuy nhiên các trường hợp rất đa dạng. Vd. tên các sheet: T1N2013, ..., T12N2013, T1N2014, ..., T12N2014 thì xử lý thế nào?

Nói chung bạn phải hiểu được thuật toán là so sánh 2 chuỗi để quyết định có đổi chỗ 2 sheet cho nhau không. Hiểu được rồi thì tùy trường hợp mà làm thêm một số thao tác sao cho kết quả so sánh đúng theo ý mình.
 
Lần chỉnh sửa cuối:
Upvote 0
Thầy siwtom cho em hỏi code này nha. ví dụ em muốn lọc ký tự đầu của 1 cell là số và cho vào sheet Number. Thì em dùng code IsNumeric. Còn nếu là chữ cái A,B,C thì cứ theo đúng tên Sheet đó mà cho vào.
Vậy còn khi ký tự đầu tiên là các ký tự đặc biệt ko phải Số và ABC như : ?-_+=.... thì làm sao phân biệt mấy cái ký tự đặc biệt đó để xóa luôn cái cell đó vậy Thầy ?

PHP:
Private Sub CommandButton10_Click()
Dim index As Long, sh As Worksheet, a
    For index = 65 To 90
        On Error Resume Next
        a = Sheets(Chr(index)).[A1].Value
        If Err.Number Then
            Err.Clear
            On Error GoTo 0
            Set sh = Worksheets.Add
            With sh
                .Name = Chr(index)
                .Range("A1").Value = Chr(index)
                .Range("A2").Value = Chr(index)
            End With
        End If
    Next index
    
'    SortSheets
End Sub

Trong đoạn code trên em thấy Thầy cho "a = Sheets(Chr(index)).[A1].Value" rồi sau đó ko thấy làm gì với cái "a" đó hết ? mục đích để làm gì vậy Thầy ???
 
Lần chỉnh sửa cuối:
Upvote 0
Thầy siwtom cho em hỏi code này nha. ví dụ em muốn lọc ký tự đầu của 1 cell là số và cho vào sheet Number. Thì em dùng code IsNumeric. Còn nếu là chữ cái A,B,C thì cứ theo đúng tên Sheet đó mà cho vào.
Vậy còn khi ký tự đầu tiên là các ký tự đặc biệt ko phải Số và ABC như : ?-_+=.... thì làm sao phân biệt mấy cái ký tự đặc biệt đó để xóa luôn cái cell đó vậy Thầy ?
Một ký tự đầu? Bạn đọc ra bằng Left hoặc Mid. Còn kiểm tra? Hàm Asc/AscW(ký tự) sẽ trả về mã của "ký tự". Mã của chữ số là từ 48 tới 57 (tương ứng 0, 1, ..., 9), của A-Z là từ 65 tới 90, của a-z là từ 97 tới 122. Nếu Asc(ký tự) nằm trong mỗi khoảng ở trên thì "ký tự" là chữ số, thuộc A-Z, thuộc a-z
Nếu dùng hàm của system thì có (lâu rồi tôi không nhớ) IsCharAlpha, IsCharAlphaNumeric

PHP:
Private Sub CommandButton10_Click()
Dim index As Long, sh As Worksheet, a
    For index = 65 To 90
        On Error Resume Next
        a = Sheets(Chr(index)).[A1].Value
        If Err.Number Then
            Err.Clear
            On Error GoTo 0
            Set sh = Worksheets.Add
            With sh
                .Name = Chr(index)
                .Range("A1").Value = Chr(index)
                .Range("A2").Value = Chr(index)
            End With
        End If
    Next index
    
'    SortSheets
End Sub

Trong đoạn code trên em thấy Thầy cho "a = Sheets(Chr(index)).[A1].Value" rồi sau đó ko thấy làm gì với cái "a" đó hết ? mục đích để làm gì vậy Thầy ???

Để thử xem sheet Sheets(Chr(index)) có tồn tại hay không. Nếu không tồn tại thì sẽ có lỗi tại dòng (đọc dữ liệu của sheet không tồn tại)
Mã:
a = Sheets(Chr(index)).[A1].Value

Trước đó có On Error Resume Next mục đích để nếu có lỗi thì còn có cơ hội xử lý. Nếu không có On Error Resume Next mà sẩy ra lỗi thì chỉ còn nước reset/end mà chả giải quyết được gì. Còn có On Error Resume Next thì khi gặp lỗi thì code vẫn chuyển sang dòng tiếp theo. Mà ở dòng tiếp theo thì tôi có code kiểm tra xem có lỗi hay không. Nếu có lỗi - If Err.Number Then thì thực hiện những code có trong If ... End If, tức các code tạo sheet mới. Nếu không có lỗi tức Sheets(Chr(index)) tồn tại thì tất nhiên code trong If ... End If không được thực hiện. Tức sẽ không tạo sheet ... đã có.

Nhiều người dùng object Err để "lờ" lỗi đi, kiểu "trát vôi lên mụn" để che nó đi. Nhưng Err được thiết kế không phải là để "lờ" lỗi đi. Nếu không có Err thì nhiều khi không làm được gì (như trong trường hợp này) hoặc khi gặp lỗi thì phải reset/end code để sửa lại chỗ có lỗi rồi lại phải run code từ đầu. Nếu code rất dài thì bạn hãy tưởng tượng là chạy lại code mất công như thế nào. Trong trường hợp ở trên ta không lờ lỗi đi mà dùng Err để có cơ hội kiểm tra lỗi có sẩy ra hay không để xử lý.
 
Upvote 0
Nhờ Chỉnh sửa lại code

Mình có viết một code chạy vòng lập. ghép các dãy số lại vối nhau kết quả ra đúng như mong muốn nhưng tốc độ ghép chậm quá do quá nhiều vòng vòng lập for Next nên tốc độ chậm lại. đó là mình mới cho cột F có khoãng 100 số mà vậy chứ cột F lên 500 => 1000 thì đơ máy luôn.
suy nghĩ mãi không thể viết được cách khác tốc độ tối ưu hơn vì vậy xin úp lên đây nhờ các bạn trợ giúp
Xin cảm ơn
PHP:
Sub Ghep_So()
Dim dauso(), duoiso, kq(), i As Long, j As Long, n As Long
With Sheet4
    duoiso = .Range(.[F3], .[F200].End(4)).Value
    ReDim kq(1 To UBound(duoiso), 1 To 1)
    dauso = .Range("A3:A74").Value
End With
For i = 1 To UBound(duoiso)
    For j = 1 To UBound(dauso)
        If duoiso(i, 1) <> "" Then
            kq(j + n, 1) = dauso(j, 1) & duoiso(i, 1)
        End If
    Next
        n = n + 72
Next
With Sheet4
    .Range("G3:G10000").ClearContents
    .Range("G3").Resize(i - 1, 1) = kq
End With
End Sub
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Một ký tự đầu? Bạn đọc ra bằng Left hoặc Mid. Còn kiểm tra? Hàm Asc/AscW(ký tự) sẽ trả về mã của "ký tự". Mã của chữ số là từ 48 tới 57 (tương ứng 0, 1, ..., 9), của A-Z là từ 65 tới 90, của a-z là từ 97 tới 122. Nếu Asc(ký tự) nằm trong mỗi khoảng ở trên thì "ký tự" là chữ số, thuộc A-Z, thuộc a-z
Nếu dùng hàm của system thì có (lâu rồi tôi không nhớ) IsCharAlpha, IsCharAlphaNumeric



Để thử xem sheet Sheets(Chr(index)) có tồn tại hay không. Nếu không tồn tại thì sẽ có lỗi tại dòng (đọc dữ liệu của sheet không tồn tại)
Mã:
a = Sheets(Chr(index)).[A1].Value

Trước đó có On Error Resume Next mục đích để nếu có lỗi thì còn có cơ hội xử lý. Nếu không có On Error Resume Next mà sẩy ra lỗi thì chỉ còn nước reset/end mà chả giải quyết được gì. Còn có On Error Resume Next thì khi gặp lỗi thì code vẫn chuyển sang dòng tiếp theo. Mà ở dòng tiếp theo thì tôi có code kiểm tra xem có lỗi hay không. Nếu có lỗi - If Err.Number Then thì thực hiện những code có trong If ... End If, tức các code tạo sheet mới. Nếu không có lỗi tức Sheets(Chr(index)) tồn tại thì tất nhiên code trong If ... End If không được thực hiện. Tức sẽ không tạo sheet ... đã có.

Nhiều người dùng object Err để "lờ" lỗi đi, kiểu "trát vôi lên mụn" để che nó đi. Nhưng Err được thiết kế không phải là để "lờ" lỗi đi. Nếu không có Err thì nhiều khi không làm được gì (như trong trường hợp này) hoặc khi gặp lỗi thì phải reset/end code để sửa lại chỗ có lỗi rồi lại phải run code từ đầu. Nếu code rất dài thì bạn hãy tưởng tượng là chạy lại code mất công như thế nào. Trong trường hợp ở trên ta không lờ lỗi đi mà dùng Err để có cơ hội kiểm tra lỗi có sẩy ra hay không để xử lý.

_ Cám ơn Thầy nhiều lắm, Thầy giải thích code rất cặn kẽ và dễ hiểu. -=.,,
 
Upvote 0
Mình có viết một code chạy vòng lập. ghép các dãy số lại vối nhau kết quả ra đúng như mong muốn nhưng tốc độ ghép chậm quá do quá nhiều vòng vòng lập for Next nên tốc độ chậm lại. đó là mình mới cho cột F có khoãng 100 số mà vậy chứ cột F lên 500 => 1000 thì đơ máy luôn.
suy nghĩ mãi không thể viết được cách khác tốc độ tối ưu hơn vì vậy xin úp lên đây nhờ các bạn trợ giúp
Xin cảm ơn
PHP:
Sub Ghep_So()
Dim dauso(), duoiso, kq(), i As Long, j As Long, n As Long
With Sheet4
    duoiso = .Range(.[F3], .[F200].End(4)).Value
    ReDim kq(1 To UBound(duoiso), 1 To 1)
    dauso = .Range("A3:A74").Value
End With
For i = 1 To UBound(duoiso)
    For j = 1 To UBound(dauso)
        If duoiso(i, 1) <> "" Then
            kq(j + n, 1) = dauso(j, 1) & duoiso(i, 1)
        End If
    Next
        n = n + 72
Next
With Sheet4
    .Range("G3:G10000").ClearContents
    .Range("G3").Resize(i - 1, 1) = kq
End With
End Sub
Bảo đảm mình code chạy trong vòng 1s là ra kết quả. Nhưng giờ đang bận.
Dạng bài này mà không dùng Dic thì chạy tới sáng luôn chưa xong
 
Lần chỉnh sửa cuối:
Upvote 0
vậy để em tập set một cái dic xem sao
Bài này chỉ khó là khi ghép dãy 6 số để tạo ra những số gần giống chỉ sai duy nhất 1 số gần nhất.
Vừa tạo ra vừa nạp vào Dic để kiểm tra duy nhất luôn. Cuối cùng duyệt qua dữ liệu đầu số nhà mạng và ghép với từng số trong dic
Bảo đảm 10 000 số chạy chưa tới 1s
 
Upvote 0
Bài này chỉ khó là khi ghép dãy 6 số để tạo ra những số gần giống chỉ sai duy nhất 1 số gần nhất.
Vừa tạo ra vừa nạp vào Dic để kiểm tra duy nhất luôn. Cuối cùng duyệt qua dữ liệu đầu số nhà mạng và ghép với từng số trong dic
Bảo đảm 10 000 số chạy chưa tới 1s

không biết em có set nỗi dic không nữa. nhưng cho dù có không ra một kết quả nào đi chăng nữa thì cũng sẽ quyết tâm set một cái dic
 
Upvote 0
Bài này chỉ khó là khi ghép dãy 6 số để tạo ra những số gần giống chỉ sai duy nhất 1 số gần nhất.
Vừa tạo ra vừa nạp vào Dic để kiểm tra duy nhất luôn. Cuối cùng duyệt qua dữ liệu đầu số nhà mạng và ghép với từng số trong dic
Bảo đảm 10 000 số chạy chưa tới 1s
Khó hiểu à nghe!
Code của tác giả bảo là ra kết quả đúng thì tôi đâu thấy có so sánh duy nhất gì đâu mà Dic?
Mình có viết một code chạy vòng lập. ghép các dãy số lại vối nhau kết quả ra đúng như mong muốn nhưng tốc độ ghép chậm quá do quá nhiều vòng vòng lập for Next nên tốc độ chậm lại. đó là mình mới cho cột F có khoãng 100 số mà vậy chứ cột F lên 500 => 1000 thì đơ máy luôn.
suy nghĩ mãi không thể viết được cách khác tốc độ tối ưu hơn vì vậy xin úp lên đây nhờ các bạn trợ giúp
Xin cảm ơn
PHP:
Sub Ghep_So()
Dim dauso(), duoiso, kq(), i As Long, j As Long, n As Long
With Sheet4
    duoiso = .Range(.[F3], .[F200].End(4)).Value
    ReDim kq(1 To UBound(duoiso), 1 To 1)
    dauso = .Range("A3:A74").Value
End With
For i = 1 To UBound(duoiso)
    For j = 1 To UBound(dauso)
        If duoiso(i, 1) <> "" Then
            kq(j + n, 1) = dauso(j, 1) & duoiso(i, 1)
        End If
    Next
        n = n + 72
Next
With Sheet4
    .Range("G3:G10000").ClearContents
    .Range("G3").Resize(i - 1, 1) = kq
End With
End Sub
Tôi chạy code này kết quả cũng giống hệt của tác giả, không kịp chớp mắt là xong.
[GPECODE=vb]Public Sub GPE()
Dim Duoi(), Dau(), Arr(), I As Long, J As Long, K As Long
Duoi = Range([F3], [F3].End(xlDown)).Value2
Dau = Range([A3], [A3].End(xlDown)).Value2
ReDim Arr(1 To UBound(Dau, 1) * UBound(Duoi, 1), 1 To 1)
For J = 1 To UBound(Duoi, 1)
For I = 1 To UBound(Dau, 1)
K = K + 1
Arr(K, 1) = Dau(I, 1) & Duoi(J, 1)
Next I
Next J
[H3:H65000].ClearContents
[H3].Resize(K) = Arr
End Sub[/GPECODE]
Hổng biết "ý đồ" dùng Dic để loại ra số nào?
 
Lần chỉnh sửa cuối:
Upvote 0
Khó hiểu à nghe!
Code của tác giả bảo là ra kết quả đúng thì tôi đâu thấy có so sánh duy nhất gì đâu mà Dic?

Tôi chạy code này kết quả cũng giống hệt của tác giả, không kịp chớp mắt là xong.
[GPECODE=vb]Public Sub GPE()
Dim Duoi(), Dau(), Arr(), I As Long, J As Long, K As Long
Duoi = Range([F3], [F3].End(xlDown)).Value2
Dau = Range([A3], [A3].End(xlDown)).Value2
ReDim Arr(1 To UBound(Dau, 1) * UBound(Duoi, 1), 1 To 1)
For J = 1 To UBound(Duoi, 1)
For I = 1 To UBound(Dau, 1)
K = K + 1
Arr(K, 1) = Dau(I, 1) & Duoi(J, 1)
Next I
Next J
[H3:H65000].ClearContents
[H3].Resize(K) = Arr
End Sub[/GPECODE]
Hổng biết "ý đồ" dùng Dic để loại ra số nào?
Kết quả ra Y trang code em viết mà tốc độ cũng chớp mắt
cảm ơn anh nhiều
 
Lần chỉnh sửa cuối:
Upvote 0
Khó hiểu à nghe!
Code của tác giả bảo là ra kết quả đúng thì tôi đâu thấy có so sánh duy nhất gì đâu mà Dic?

Tôi chạy code này kết quả cũng giống hệt của tác giả, không kịp chớp mắt là xong.

Hổng biết "ý đồ" dùng Dic để loại ra số nào?
Không nói hết căn cơ gốc ngọn cho anh nghe đâu. Đâu có cái gì tự nhiên.. ka ka ka
 
Lần chỉnh sửa cuối:
Upvote 0
Mình có viết một code chạy vòng lập. ghép các dãy số lại vối nhau kết quả ra đúng như mong muốn nhưng tốc độ ghép chậm quá do quá nhiều vòng vòng lập for Next nên tốc độ chậm lại. đó là mình mới cho cột F có khoãng 100 số mà vậy chứ cột F lên 500 => 1000 thì đơ máy luôn.
suy nghĩ mãi không thể viết được cách khác tốc độ tối ưu hơn vì vậy xin úp lên đây nhờ các bạn trợ giúp
Xin cảm ơn
PHP:
Sub Ghep_So()
Dim dauso(), duoiso, kq(), i As Long, j As Long, n As Long
With Sheet4
    duoiso = .Range(.[F3], .[F200].End(4)).Value
    ReDim kq(1 To UBound(duoiso), 1 To 1)
    dauso = .Range("A3:A74").Value
End With
For i = 1 To UBound(duoiso)
    For j = 1 To UBound(dauso)
        If duoiso(i, 1) <> "" Then
            kq(j + n, 1) = dauso(j, 1) & duoiso(i, 1)
        End If
    Next
        n = n + 72
Next
With Sheet4
    .Range("G3:G10000").ClearContents
    .Range("G3").Resize(i - 1, 1) = kq
End With
End Sub

Nếu bạn chịu khó debug, bảo code nó in ra UBound(duoiso) thì sẽ thấy là 1048574. Tính hàng triệu như vậy có máy thánh mới không lâu.
Điều này chứng tỏ code tính ô dữ liệu cuối cùng của bạn sai.
Hãy tự tìm hiểu sai ra sao.
 
Upvote 0
Khó hiểu à nghe!
Code của tác giả bảo là ra kết quả đúng thì tôi đâu thấy có so sánh duy nhất gì đâu mà Dic?
...........
Hổng biết "ý đồ" dùng Dic để loại ra số nào?
Gởi anh BaTê nhà mình cái vụ tại sao phải dùng Dic nha, nếu không anh sẽ ấm ức tại sao em lại nói như thế
Anh có ngon thì đừng dùng Dic nha... hí hí
Yêu Cầu:
1. Cho sẵn dữ liệu tại cột A và cột E
2. Code thế nào để tại cột cột F và G có kết quả như mẫu là I và J

PS: cứ mỗi chuỗi 6 số tạo ra những số chỉ khác nhau 1 số so với chuỗi gốc. Ví dụ 597598 thì sẽ có 4 59758, 6 97598, 587598, ....... tới hết chuỗi
số 9 thì không cộng lên, số 0 thì không trừ xuống.
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Hi Cac Anh
Cac Anh có thể giải thích cho em biết nội dung đoạn CODE sau không
Chẳn hạn như đoạn sau số 9 này là gì
Arr(r, 9) = r + 5

Private Sub TextBox9_AfterUpdate()
Dim Arr(), Darr(), i As Long, k As Long, j As Integer, r As Long
Arr = Sheets("nhap").Range("A6:H" & Sheets("nhap").Range("C65536").End(xlUp).Row).Valu e
ReDim Preserve Arr(1 To UBound(Arr, 1), 1 To UBound(Arr, 2) + 1)
For r = 1 To UBound(Arr, 1)
Arr(r, 9) = r + 5
Next r
ReDim Darr(1 To UBound(Arr, 1), 1 To UBound(Arr, 2))
For i = 1 To UBound(Arr, 1)
If Arr(i, 1) = Val(TextBox9.Value) Then
k = k + 1
Darr(k, 1) = Format(Arr(i, 2), "dd/mm/yy")
For j = 2 To UBound(Darr, 2) - 1
Darr(k, j) = Arr(i, j + 1)
Next j
End If
Next i
ListBox1.List = Darr
Sheet2.Range("A1").Resize(UBound(Darr, 1), UBound(Darr, 2)) = Darr
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Xin các Thầy giúp hoàn thiện code vòng lặp này !!!

Em làm 1 cái code vòng lặp tạo ký tự như sau.

PHP:
Sub vlap()
Dim i As Long, j As Long
b = 1
For i = 97 To 122
       For j = 97 To 122
              Activesheet.Range("A" & b).Value = Chr(i) & Chr(j)
              b = b + 1
       Next j
Next i
End Sub

_ Đoan code trên nó sẽ tạo cho em dãy ký tự từ aa -> zz. Giờ em muốn nó có a0 - z9 và 00 - 99 thì em phải thêm cái i = 48 To 57 và j = 48 To 57 vào chỗ nào vậy các Thầy ???.
_ Tóm lại ý em muốn hỏi là làm sao để gắn giá trị i hoặc j = 2 khoảng ko liên tiếp nhau đó (48 To 57 và 97 To 122)
 
Lần chỉnh sửa cuối:
Upvote 0
Status
Không mở trả lời sau này.
Web KT

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

Back
Top Bottom