Chuyên mục xử lý, gỡ rối code VBA (4 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,965
    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)

    PHP:
    Sub vlap()
    Dim i As Long, j As Long, b
    For i = 97 To 122
       For j = 48 To 122
          If j < 58 Or j > 96 Then
             b = b + 1
             ActiveSheet.Range("A" & b).Value = Chr(i) & Chr(j)
          End If
       Next j
    Next i
    End Sub
     
    Upvote 0
    PHP:
    Sub vlap()
    Dim i As Long, j As Long, b
    For i = 97 To 122
       For j = 48 To 122
          If j < 58 Or j > 96 Then
             b = b + 1
             ActiveSheet.Range("A" & b).Value = Chr(i) & Chr(j)
          End If
       Next j
    Next i
    End Sub

    _ Theo em hiểu thì code Thầy chỉnh lại i vẫn chỉ có giá trị từ 97 To 122 thôi. Vậy làm sao để i cũng xét qua giá trị từ 48 To 57 vậy Thầy. Bởi vì em cần cho cả 2 biến i và j chạy trong 2 khoảng 48 To 57 và 97 To 122 đó.
    _ Mình có thể gán cho giá trị i trong For ... Next ở nhiều khoảng ko liền nhau ko Thầy ?
     
    Upvote 0
    _ Theo em hiểu thì code Thầy chỉnh lại i vẫn chỉ có giá trị từ 97 To 122 thôi. Vậy làm sao để i cũng xét qua giá trị từ 48 To 57 vậy Thầy. Bởi vì em cần cho cả 2 biến i và j chạy trong 2 khoảng 48 To 57 và 97 To 122 đó.
    _ Mình có thể gán cho giá trị i trong For ... Next ở nhiều khoảng ko liền nhau ko Thầy ?
    Trả lời liều chứ thật ra chả hiểu bạn muốn kết quả ra sao
    PHP:
    Sub vlap()
    Dim i As Long, j As Long, b
    Dim res(1 To 65536, 1 To 1)
    For i = 48 To 122
       If i < 58 Or i > 96 Then
          For j = 48 To 122
             If j < 58 Or j > 96 Then
                b = b + 1
                res(b, 1) = Chr(i) & Chr(j)
             End If
          Next j
       End If
    Next i
    [A1].Resize(b) = res
    End Sub
     
    Upvote 0
    Trả lời liều chứ thật ra chả hiểu bạn muốn kết quả ra sao
    PHP:
    Sub vlap()
    Dim i As Long, j As Long, b
    Dim res(1 To 65536, 1 To 1)
    For i = 48 To 122
       If i < 58 Or i > 96 Then
          For j = 48 To 122
             If j < 58 Or j > 96 Then
                b = b + 1
                res(b, 1) = Chr(i) & Chr(j)
             End If
          Next j
       End If
    Next i
    [A1].Resize(b) = res
    End Sub

    _ Haha Cám ơn Thầy nhiều nha, em cũng làm theo cái vụ "If" như Thầy thì ra kết quả cũng OK, chỉ tội là càng nhiều khoảng giá trị ko liền nhau thì càng nhiều "If" **~**.
    _ Còn đoạn kết trên của Thầy thì em thấy Thầy "Update" cái dòng :
    PHP:
    ActiveSheet.Range("A" & b).Value = Chr(i) & Chr(j)
    thành :
    PHP:
    res(b, 1) = Chr(i) & Chr(j)
    _ Tốc độ nhanh lên thấy rõ luôn ghê thiệt... Cám ơn Thầy Hải nhiều lắm --=0
     
    Lần chỉnh sửa cuối:
    Upvote 0
    _ Còn đoạn kết trên của Thầy thì em thấy Thầy "Update" cái dòng :
    PHP:
    ActiveSheet.Range("A" & b).Value = Chr(i) & Chr(j)
    thành :
    PHP:
    res(b, 1) = Chr(i) & Chr(j)
    _ Tốc độ nhanh lên thấy rõ luôn ghê thiệt... Cám ơn Thầy Hải nhiều lắm --=0

    Đó là cách xử lý trên mảng, khi dùng mảng, ta cập nhật, tính toán toàn bộ trên bộ nhớ của máy, sau đó gán xuống sheet một lần, dĩ nhiên sẽ cho tốc độ nhanh hơn là mỗi lần tính toán, mỗi lần sẽ gán xuống sheet.
     
    Upvote 0
    _ Haha Cám ơn Thầy nhiều nha, em cũng làm theo cái vụ "If" như Thầy thì ra kết quả cũng OK, chỉ tội là càng nhiều khoảng giá trị ko liền nhau thì càng nhiều "If" **~**.
    _

    thử giải pháp này cho nó nhanh (không mất thời gian chạy không công từ 49 đến 96) và không cần if, thích tăng bao nhiêu khoảng cũng được
    PHP:
    Sub vlap()
    Dim i As Long, j As Long, b As Long, ik As Long
    Dim d1, c1, d2, c2, res(1 To 65536, 1 To 1)
    
    d1 = Array(48, 48, 97, 97)
    c1 = Array(57, 57, 122, 122)
    d2 = Array(48, 97, 48, 97)
    c2 = Array(57, 122, 97, 122)
    
    For ik = 0 To Ubound(d1)
        For i = d1(ik) To c1(ik)
            For j = d2(ik) To c2(ik)
                b = b + 1
                res(b, 1) = Chr(i) & Chr(j)
            Next j
        Next i
    Next ik
    
    [A1].Resize(b) = res
    End Sub
     
    Lần chỉnh sửa cuối:
    Upvote 0
    thử giải pháp này cho nó nhanh (không mất thời gian chạy không công từ 49 đến 96) và không cần if, thích tăng bao nhiêu khoảng cũng được
    PHP:
    Sub vlap()
    Dim i As Long, j As Long, b As Long, ik As Long
    Dim d1, c1, d2, c2, res(1 To 65536, 1 To 1)
    
    d1 = Array(48, 48, 97, 97)
    c1 = Array(57, 57, 122, 122)
    d2 = Array(48, 97, 48, 97)
    c2 = Array(57, 122, 97, 122)
    
    For ik = 0 To Ubound(d1)
        For i = d1(ik) To c1(ik)
            For j = d2(ik) To c2(ik)
                b = b + 1
                res(b, 1) = Chr(i) & Chr(j)
            Next j
        Next i
    Next ik
    
    [A1].Resize(b) = res
    End Sub

    _ Giải thích 1 chút về code trên được không Zerothink. Nhiều mảng quá nhìn ko hiểu gì luôn **~**
     
    Upvote 0
    _ Giải thích 1 chút về code trên được không Zerothink. Nhiều mảng quá nhìn ko hiểu gì luôn **~**

    Bạn biết code lập trình nên cần chú ý chút là dễ hiểu ngay,

    cái đó giờ bạn cứ giả định dịch vòng lặp FOR IK: ik từ 0 đến 3 xem sao, ví như

    lần 1:
    ik=0
    ==> code tương 2 vòng lặp for i và for j tương đương
    PHP:
        For i = 48 To 57
            For j = 48 To 57
                b = b + 1
                res(b, 1) = Chr(i) & Chr(j)
            Next j
        Next i
    vì d1(0)=48; c1(0)=57; d2(0)=48; c2(0)=57
    chú ý: d,c đặt tên biến viết tắt bởi dẦU, cUỐI

    lần 2:
    ik=1
    ==> code tương 2 vòng lặp for i và for j tương đương
    PHP:
        For i = 48 To 57
            For j = 97 To 122
                b = b + 1
                res(b, 1) = Chr(i) & Chr(j)
            Next j
        Next i
    vì d1(1)=48; c1(1)=57; d2(1)= 97 ; c2(1)= 122


    như thế các mảng hằng số d1,c1,d2,c2 là lưu vị trí đầu cuối cho for i và for j --như thế ta có thể tăng thêm các khoảng mà bao nhiêu ta thích
    Cứ vậy tiếp tục cho là bạn hiểu
    lẩn 3: ik=2
    lần 4: ik=3 (=ubound(d1))

    là tại sao lại như thế,
     
    Lần chỉnh sửa cuối:
    Upvote 0
    Bạn biết code lập trình nên cần chú ý chút là dễ hiểu ngay,

    cái đó giờ bạn cứ giả định dịch vòng lặp FOR IK: ik từ 0 đến 3 xem sao, ví như

    lần 1:
    ik=0
    ==> code tương 2 vòng lặp for i và for j tương đương
    PHP:
        For i = 48 To 57
            For j = 48 To 57
                b = b + 1
                res(b, 1) = Chr(i) & Chr(j)
            Next j
        Next i
    vì d1(0)=48; c1(0)=57; d2(0)=48; c2(0)=57
    chú ý: d,c đặt tên biến viết tắt bởi dẦU, cUỐI

    lần 2:
    ik=1
    ==> code tương 2 vòng lặp for i và for j tương đương
    PHP:
        For i = 48 To 57
            For j = 97 To 122
                b = b + 1
                res(b, 1) = Chr(i) & Chr(j)
            Next j
        Next i
    vì d1(1)=48; c1(1)=57; d2(1)= 97 ; c2(1)= 122


    như thế các mảng hằng số d1,c1,d2,c2 là lưu vị trí đầu cuối cho for i và for j --như thế ta có thể tăng thêm các khoảng mà bao nhiêu ta thích
    Cứ vậy tiếp tục cho là bạn hiểu
    lẩn 3: ik=2
    lần 4: ik=3 (=ubound(d1))

    là tại sao lại như thế,


    _ À ha, Hiểu rồi, vậy là ik chỉ là vòng lặp trung gian để lấy giá trị đầu và cuối cho 2 vòng i và j. Thế thì trong code của bạn có 1 chỗ ghi sai rùi hehe :
    PHP:
    c2 = Array(57, 122, 97, 122)
    phải là :
    PHP:
    c2 = Array(57, 122, 57, 122)
     
    Upvote 0
    _ À ha, Hiểu rồi, vậy là ik chỉ là vòng lặp trung gian để lấy giá trị đầu và cuối cho 2 vòng i và j. Thế thì trong code của bạn có 1 chỗ ghi sai rùi hehe :
    PHP:
    c2 = Array(57, 122, 97, 122)
    phải là :
    PHP:
    c2 = Array(57, 122, 57, 122)


    Không. chú ý là For j chạy từ d2(ik) đến c2(ik) nhé,

    hình như bạn thay đổi giá trị sai (??? cái này còn tùy việc lặp các khoảng thế nào)
     
    Upvote 0
    thử giải pháp này cho nó nhanh (không mất thời gian chạy không công từ 49 đến 96) và không cần if, thích tăng bao nhiêu khoảng cũng được
    PHP:
    Sub vlap()
    Dim i As Long, j As Long, b As Long, ik As Long
    Dim d1, c1, d2, c2, res(1 To 65536, 1 To 1)
    
    d1 = Array(48, 48, 97, 97)
    c1 = Array(57, 57, 122, 122)
    d2 = Array(48, 97, 48, 97)
    c2 = Array(57, 122, 97, 122)
    
    For ik = 0 To Ubound(d1)
        For i = d1(ik) To c1(ik)
            For j = d2(ik) To c2(ik)
                b = b + 1
                res(b, 1) = Chr(i) & Chr(j)
            Next j
        Next i
    Next ik
    
    [A1].Resize(b) = res
    End Sub

    Mình không tin là nhanh hơn giải pháp 2 vòng lặp đâu
    Ai không tin thì cứ cho code chạy thử 10 vòng thì biết liền

    Có điều dùng 3 vòng lặp có vẻ chuyên nghiệp, còn 2 vòng lặp có vẻ nông dân nhưng lại dễ hiểu.
     
    Upvote 0
    Mình không tin là nhanh hơn giải pháp 2 vòng lặp đâu
    Ai không tin thì cứ cho code chạy thử 10 vòng thì biết liền

    Có điều dùng 3 vòng lặp có vẻ chuyên nghiệp, còn 2 vòng lặp có vẻ nông dân nhưng lại dễ hiểu.

    Có thể, vì số vòng lặp không công cũng không nhiều, nên so sánh khó,

    Nhưng code sau thì đỡ phải chạy không công, và quan trọng là người hỏi muốn tăng số khoảng lên,

    Đây chỉ là ví dụ thui, chả hiểu ng hỏi ứng dụng gì, làm chơi chơi ấy mà
     
    Upvote 0
    Trong VBA có cú pháp Select Case có thể dùng để thay thế IF nhiều khoảng. Trong trường hợp này muốn bao nhiêu khoảng thì cứ việc ghi thêm.

    tb. vòng lặp For (chỉ số) chỉ gồm toàn toán số nguyên cho nên vòng nhanh lắm. Chạy không cũng chẳng chết ai.

    === bổ sung 09/08/2014 ===

    Nếu nhất định muốn dùng mảng thì có thể dùng lệnh evaluate để tạo mảng 2 chiều, thay vì hàm Array chỉ tạo được mảng 1 chiều.

    Mã:
    Sub vlap()
    Dim i As Long, j As Long, b As Long, ik As Long
    Dim d1, d2, res(1 To 65536, 1 To 1)
    
    d1 = [ { 48, 57; 48, 57; 97, 122; 97, 122 } ]
    d2 = [ { 48, 57; 97, 122; 48, 97; 97, 122 } ]
    
    
    For ik = 1 To UBound(d1)
        For i = d1(ik, 1) To d1(ik, 2)
            For j = d2(ik, 1) To d2(ik, 2)
    ...
    
    End Sub
     
    Lần chỉnh sửa cuối:
    Upvote 0
    PHP:
    Sub vlap2()
    Dim name As String, b As Long, i As Long, j As Long
    Dim res(1 To 1048576, 1 To 1)
    name = UserForm1.TextBox5.Text
    b = 1
    For i = 0 To 9
        For j = 0 To 9
            b = b + 1
            res(b, 1) = name & i & j
        Next j
    Next i
    [A2].Resize(b) = res
    Call ExportFile
    End Sub

    _ Em có đoạn code như trên và 1 cột H chứa nhiều tên, giờ em muốn cái "name" sẽ tự lấy từng tên trong cột H đó. (khỏi phải nhập tên từng người vào cái TextBox5 nữa. Nhưng em không biết làm sao để tạo vòng lặp đưa tên từng người vào. Xin các Thầy giúp em nha %#^#$
     
    Lần chỉnh sửa cuối:
    Upvote 0
    PHP:
    Sub vlap2()
    Dim name As String, b As Long, i As Long, j As Long
    Dim res(1 To 1048576, 1 To 1)
    name = UserForm1.TextBox5.Text
    b = 1
    For i = 0 To 9
        For j = 0 To 9
            b = b + 1
            res(b, 1) = name & i & j
        Next j
    Next i
    [A2].Resize(b) = res
    Call ExportFile
    End Sub

    _ Em có đoạn code như trên và 1 cột H chứa nhiều tên, giờ em muốn cái "name" sẽ tự lấy từng tên trong cột H đó. (khỏi phải nhập tên từng người vào cái TextBox5 nữa. Nhưng em không biết làm sao để tạo vòng lặp đưa tên từng người vào. Xin các Thầy giúp em nha %#^#$

    _ hehe, tự nghĩ ra luôn rồi :). Các Thầy coi có gì góp ý hoàn thiện hơn giúp em nha %#^#$

    PHP:
    Sub vlap2()
    Dim name As String, b As Long, i As Long, j As Long
    Dim res(1 To 1048576, 1 To 1), LastRow As Long, ik As Long
    LastRow = Range("H1048576").End(xlUp).Row
    For ik = 1 To LastRow
    name = Sheets("Sheet1").Range("H" & ik).Text
    b = 1
    For i = 0 To 9
        For j = 0 To 9
            b = b + 1
            res(b, 1) = name & i & j
        Next j
    Next i
    [A2].Resize(b) = res
    Call ExportFile
    Next ik
    End Sub
     
    Upvote 0
    Hiện tại mình mượn code trên diễn đàn và tạo Form sau "KIEM KE"
    1. Mình muốn nhập 1 lần từ 1 dòng hay 5 dòng hoặc tất cả các dòng trên Form
    2. kiêm tra dùm nút sữa chữa bi lỗi gì
    Private Sub CommandButton3_Click()
    Dim curRow As Long
    curRow = ListBox1.List(ListBox1.ListIndex, ListBox1.ColumnCount)
    Sheets("nhaplieu").Cells(curRow, 2) = TextBox6.Value
    Sheets("nhaplieu").Cells(curRow, 3) = TextBox2.Value
    Sheets("nhaplieu").Cells(curRow, 4) = TextBox4.Value
    Sheets("nhaplieu").Cells(curRow, 5) = TextBox5.Value
    End Sub


    Private Sub CommandButton4_Click()
    Unload UserForm2
    End Sub
    Private Sub ListBox1_Change()
    If ListBox1.ListIndex <> -1 Then
    TextBox6.Value = ListBox1.List(ListBox1.ListIndex, 0)
    TextBox2.Value = ListBox1.List(ListBox1.ListIndex, 1)
    TextBox4.Value = ListBox1.List(ListBox1.ListIndex, 2)
    TextBox5.Value = ListBox1.List(ListBox1.ListIndex, 3)
    End If
    End Sub


    Private Sub TextBox1_AfterUpdate()
    Dim Arr(), Darr(), i As Long, k As Long, j As Integer, r As Long
    Arr = Sheets("nhaplieu").Range("A6:H" & Sheets("nhaplieu").Range("B65536").End(xlUp).Row).Value
    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(TextBox1.Value) Then
    k = k + 1
    Darr(k, 1) = Arr(i, 2)
    For j = 2 To UBound(Darr, 2) - 1
    Darr(k, j) = Arr(i, j + 1)
    Next j
    End If
    Next i
    ListBox1.List = Darr
    End Sub

    do up file nhieu qua khong cho up
    các anh co biet cach nao xoa khong
    các anh GPE sữa dùm luôn nha.
     
    Upvote 0
    Hiện tại mình mượn code trên diễn đàn và tạo Form sau "KIEM KE"
    1. Mình muốn nhập 1 lần từ 1 dòng hay 5 dòng hoặc tất cả các dòng trên Form
    2. kiêm tra dùm nút sữa chữa bi lỗi gì
    ....

    do up file nhieu qua khong cho up
    các anh co biet cach nao xoa khong
    ...

    bạn vào kiểm tra/ xử lý hết các File đã Up lên diễn đàn theo các bước sau:

    B1.png

    bên tay trái, phía dưới

    B2.jpg

    B3.jpg

    '------
    nếu file quan trọng (đang hỏi) thì bạn Up tạm lên MediaFire, sau đó lấy đường Link thay thế File đính kèm đó
     
    Upvote 0
    Hiện tại mình mượn code trên diễn đàn và tạo Form sau "KIEM KE"
    1. Mình muốn nhập 1 lần từ 1 dòng hay 5 dòng hoặc tất cả các dòng trên Form
    2. kiêm tra dùm nút sữa chữa bi lỗi gì
    Private Sub CommandButton3_Click()
    Dim curRow As Long
    curRow = ListBox1.List(ListBox1.ListIndex, ListBox1.ColumnCount)

    .....

    Bạn nên cho phần code (sub) vào trong tag
    Mã:
     bằng cách bấm vào nút # trên khung trả lời (ở diễn đàn) khi viết bài
    
    Còn upFile như bài trên [URL="http://www.giaiphapexcel.com/forum/member.php?853099-phucbugis"][B][B]phucbugis[/B][/B][/URL] đã nói, chắc file dung lượng to, thì up lên media file rui đưa link ra đây. vì trông vào code không khó đoán
     
    Upvote 0
    em viết code như thế này:
    range("a3").copy
    destination:= range("d5:f8")
    không biết sai chổ nào mà bao lổi. pac nào biết chỉ dùm.!
     
    Upvote 0
    Bạn nên cho phần code (sub) vào trong tag
    Mã:
     bằng cách bấm vào nút # trên khung trả lời (ở diễn đàn) khi viết bài
    
    Còn upFile như bài trên [URL="http://www.giaiphapexcel.com/forum/member.php?853099-phucbugis"][B][B]phucbugis[/B][/B][/URL] đã nói, chắc file dung lượng to, thì up lên media file rui đưa link ra đây. vì trông vào code không khó đoán[/QUOTE]
    Chỉnh sửa dùm code nhập liệu
    Mình muốn nhập 1 lần từ 5 dòng hay 8 dòng hay tất cả
     
    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