Chuyên đề giải đáp những thắc mắc về code VBA

Liên hệ QC

maytinhvp01

Thành viên thường trực
Tham gia
27/7/13
Bài viết
390
Được thích
179
Mình muốn nhờ giải thich câu lệnh " If Ran.Cells(d, c) > max Then max = Ran.Cells(d, c) "
trong ví du:
Public Function LonNhat(Ran As Range)
Dim max As Double, v As Integer, d As Integer, c As Integer
max = Ran.Cells(1, 1)
For d = 1 To Ran.Rows.Count
For c = 1 To Ran.Columns.Count
If Ran.Cells(d, c) > max Then max = Ran.Cells(d, c)
Next c
Next d
v = Tim(max, Ran)
LonNhat = max
End Function
-------------------------------------------------------
[INFO1]Thông báo:
Vì topic này:
http://www.giaiphapexcel.com/forum/...ải-thích-các-code-đề-nghị-các-bạn-gửi-vào-đây
đã quá dài nên BQT đóng lại.
Nay tôi mở topic mới với cùng chủ đề: GIẢI THÍCH NHỮNG THẮC MẮC VỀ CODE
Các bạn nếu có nhu cầu giải thích code, vui lòng post tại đây nhé
NDU96081631

[/INFO1]
 
Chỉnh sửa lần cuối bởi điều hành viên:
function nằm ở sheet riêng, em chưa biết cách làm, anh vào xem dùm em với ạ

- Thiết lập mặc định trong VBE, có thêm Option Explicit đi.
- Code xong chạy Debug xem nó có lỗi không.
- Chưa biết code chạy ổn không thì thêm ISERROR() thì làm sao biết nó lỗi gì.

Tóm lại: Sai khai báo biến LenText vs LenTex
 
Upvote 0
Chưa học đi đã lo chạy là vậy đó.
Nên tìm tài liệu học về tầm vực của biến, của các hàm và phương thức. Căn bản về modules.
 
Upvote 0
Chào các bạn. Mong các bạn giúp tôi vấn đề về lọc dữ liệu (Filter):
Trong file đính kèm tôi có bảng dữ liệu và 3 nút bấm có tên là AutoFilter 1, AutoFilter 2, AutoFilter 3. Tôi muốn khi bấm vào nút AutoFilter 1 thì ở cột B (tháng 1) toàn bộ nhân viên được xếp loại A sẽ được lọc; tương tự, nút AutoFilter 2, cột C (tháng 2) nhân viên xếp loại B được lọc; nút AutoFilter 3, cột D (tháng 3) nhân viên xếp loại C được lọc.
Tôi đã thử với đoạn code sau nhưng báo lỗi AutoFilter method of Range class failed khi bấm chuyển đổi giữa các nút (bấm nút AutoFilter1 lần 1 => code chạy; Bấm nút AutoFilter1 lần 2 => code báo lỗi; hoặc bấm AutoFilter2 => code báo lỗi).
Mong các bạn trong diễn đàn có cách nào để có thể bấm chuyển đổi qua lại giữa các nút AutoFilter mà thực hiện được tính năng Filter của excel.
Mã:
Private Sub CommandButton1_Click()
With Sheet1
    .Range("B2").AutoFilter
    .Range("B2:B17").AutoFilter Field:=2, Criteria1:="A"
End With
End Sub
-------------------------------------------------------
Private Sub CommandButton2_Click()
With Sheet1
    .Range("D2").AutoFilter
    .Range("D2").Select
    .Range("D3:D17").AutoFilter Field:=4, Criteria1:="C"
End With
End Sub
--------------------------------------------------------
Private Sub CommandButton3_Click()
With Sheet1
    .Range("C2").AutoFilter
    .Range("C2:C17").AutoFilter Field:=3, Criteria1:="B"
End With
End Sub
 

File đính kèm

Upvote 0
Tại bất kỳ một cột nào, em bắt đầu chọn từ dòng thứ 4 xuống thì bây giờ làm sao để code sẽ chọn ô thứ 2 của cột đó
Em ví dụ: Em sẽ chọn từ F4 đến xuống 1 ô bất kỳ trong cột F thì làm sao để code nhảy đến ô F2
Hoặc Em sẽ chọn từ G4 đến xuống 1 ô bất kỳ trong cột G thì làm sao để code nhảy đến ô G2
Em cảm ơn!
 
Upvote 0
Tại bất kỳ một cột nào, em bắt đầu chọn từ dòng thứ 4 xuống thì bây giờ làm sao để code sẽ chọn ô thứ 2 của cột đó
Em ví dụ: Em sẽ chọn từ F4 đến xuống 1 ô bất kỳ trong cột F thì làm sao để code nhảy đến ô F2
Hoặc Em sẽ chọn từ G4 đến xuống 1 ô bất kỳ trong cột G thì làm sao để code nhảy đến ô G2
Em cảm ơn!
Bạn thử.
Mã:
Range("G4").Offset(-2).Value
 
Upvote 0
Cảm ơn các bạn mình đã sửa nó là
Mã:
Selection.End(3).Offset(1).Select
thì OK
 
Upvote 0
Làm sao khi bấm Ctrl+F thì trong khung Find what: luôn là giá trị của ô B2 sheet Tenhang
Em ví dụ:
Nếu ô B2 sheet Tenhang là 123 thì code là
PHP:
Cells.Find(What:="123", After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _
        xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
        , SearchFormat:=False).Activate
Nhưng nếu ô B2 sheet Tenhang là 456 thì code là
PHP:
Cells.Find(What:="456", After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _
        xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
        , SearchFormat:=False).Activate
Vì do em thường xuyên copy ô B2 sheet Tenhang sau đó bấm Ctrl+F rồi paste vào khung Find what để tìm kiếm
Em cảm ơn!
 
Upvote 0
Bạn thử.
Mã:
Cells.Find(What:=sheets("tenhang").range("B2").value, After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _

        xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _

        , SearchFormat:=False).Activate
 
Upvote 0
Em có 1 AddIns tên là Doiso, em lưu trữ nó trong ổ đĩa D:/AddIns và em đã làm Addins, trong Doiso đó có Sub Docchuthanhso()
Bây giờ em muối gọi code (Docchuthanhso) thì gọi bằng cách nào
Ví dụ:em làm như sau
Sub Tonghop()
Call Docchuthanhso
End Sub
thì không được
vậy muốn gọi 1 sub của 1 addins thì gọi bằng cách nào? (vì em muốn lồng nhiều sub khác nhau vào 1 sub) Em cảm ơn!
 
Upvote 0
Chào các anh chị, em có viết VBA cho báo cáo của mình, em sử dụng Countifs trong VBA thay cho hàm có sẵn, không biết còn cách viết nào tối ưu hơn không ạ. Em cảm ơn.
Mã:
Sub bcthang()
i = 13
While i < 27
    With Sheet1
    .Range("C" & i).Value = WorksheetFunction.CountIfs(Sheet5.Range("F:F"), .Range("B" & i), _
Sheet5.Range("G:G"), "A91.A", Sheet5.Range("H:H"), ">=" & CLng(.Range("A7").Value), Sheet5.Range("H:H"), _
"<=" & CLng(.Range("G7").Value))
    If .Range("C" & i).Value <> 0 Then
    .Range("D" & i).Value = WorksheetFunction.CountIfs(Sheet5.Range("F:F"), .Range("B" & i), _
Sheet5.Range("G:G"), "A91.A", Sheet5.Range("H:H"), ">=" & CLng(.Range("A7").Value), Sheet5.Range("H:H"), _
"<=" & CLng(.Range("G7").Value), Sheet5.Range("L:L"), "<=15")
    .Range("E" & i).Value = WorksheetFunction.CountIfs(Sheet5.Range("F:F"), .Range("B" & i), _
Sheet5.Range("G:G"), "A91.A", Sheet5.Range("H:H"), ">=" & CLng(.Range("N1").Value), Sheet5.Range("H:H"), _
"<=" & CLng(.Range("G7").Value))
Else
    .Range("D" & i).Value = 0
    .Range("E" & i).Value = WorksheetFunction.CountIfs(Sheet5.Range("F:F"), .Range("B" & i), _
Sheet5.Range("G:G"), "A91.A", Sheet5.Range("H:H"), ">=" & CLng(.Range("N1").Value), Sheet5.Range("H:H"), _
"<=" & CLng(.Range("G7").Value))
End If
  .Range("F" & i).Value = WorksheetFunction.CountIfs(Sheet5.Range("F:F"), .Range("B" & i), _
Sheet5.Range("G:G"), "A91.C", Sheet5.Range("H:H"), ">=" & CLng(.Range("A7").Value), Sheet5.Range("H:H"), _
"<=" & CLng(.Range("G7").Value))
    If .Range("F" & i).Value <> 0 Then
    .Range("G" & i).Value = WorksheetFunction.CountIfs(Sheet5.Range("F:F"), .Range("B" & i), _
Sheet5.Range("G:G"), "A91.C", Sheet5.Range("H:H"), ">=" & CLng(.Range("A7").Value), Sheet5.Range("H:H"), _
"<=" & CLng(.Range("G7").Value), Sheet5.Range("L:L"), "<=15")
    .Range("H" & i).Value = WorksheetFunction.CountIfs(Sheet5.Range("F:F"), .Range("B" & i), _
Sheet5.Range("G:G"), "A91.C", Sheet5.Range("H:H"), ">=" & CLng(.Range("N1").Value), Sheet5.Range("H:H"), _
"<=" & CLng(.Range("G7").Value))
Else
    .Range("G" & i).Value = 0
    .Range("H" & i).Value = WorksheetFunction.CountIfs(Sheet5.Range("F:F"), .Range("B" & i), _
Sheet5.Range("G:G"), "A91.C", Sheet5.Range("H:H"), ">=" & CLng(.Range("N1").Value), Sheet5.Range("H:H"), _
"<=" & CLng(.Range("G7").Value))
End If
.Range("K" & i).Value = WorksheetFunction.CountIfs(Sheet5.Range("F:F"), .Range("B" & i), _
Sheet5.Range("G:G"), "TV", Sheet5.Range("H:H"), ">=" & CLng(.Range("A7").Value), Sheet5.Range("H:H"), _
"<=" & CLng(.Range("G7").Value))
    If .Range("K" & i).Value <> 0 Then
    .Range("L" & i).Value = WorksheetFunction.CountIfs(Sheet5.Range("F:F"), .Range("B" & i), _
Sheet5.Range("G:G"), "TV", Sheet5.Range("H:H"), ">=" & CLng(.Range("A7").Value), Sheet5.Range("H:H"), _
"<=" & CLng(.Range("G7").Value), Sheet5.Range("L:L"), "<=15")
    .Range("M" & i).Value = WorksheetFunction.CountIfs(Sheet5.Range("F:F"), Sheet4.Range("B" & i), _
Sheet5.Range("G:G"), "TV", Sheet5.Range("H:H"), ">=" & CLng(.Range("N1").Value), Sheet5.Range("H:H"), _
"<=" & CLng(.Range("G7").Value))
Else
    .Range("L" & i).Value = 0
    .Range("M" & i).Value = WorksheetFunction.CountIfs(Sheet5.Range("F:F"), .Range("B" & i), _
Sheet5.Range("G:G"), "TV", Sheet5.Range("H:H"), ">=" & CLng(.Range("N1").Value), Sheet5.Range("H:H"), _
"<=" & CLng(.Range("G7").Value))
End If
i = i + 1
End With
Wend
End Sub
 
Upvote 0
Chào các anh chị, em có viết VBA cho báo cáo của mình, em sử dụng Countifs trong VBA thay cho hàm có sẵn, không biết còn cách viết nào tối ưu hơn không ạ. Em cảm ơn.
Mã:
Sub bcthang()
i = 13
While i < 27
    With Sheet1
    .Range("C" & i).Value = WorksheetFunction.CountIfs(Sheet5.Range("F:F"), .Range("B" & i), _
Sheet5.Range("G:G"), "A91.A", Sheet5.Range("H:H"), ">=" & CLng(.Range("A7").Value), Sheet5.Range("H:H"), _
"<=" & CLng(.Range("G7").Value))
    If .Range("C" & i).Value <> 0 Then
    .Range("D" & i).Value = WorksheetFunction.CountIfs(Sheet5.Range("F:F"), .Range("B" & i), _
Sheet5.Range("G:G"), "A91.A", Sheet5.Range("H:H"), ">=" & CLng(.Range("A7").Value), Sheet5.Range("H:H"), _
"<=" & CLng(.Range("G7").Value), Sheet5.Range("L:L"), "<=15")
    .Range("E" & i).Value = WorksheetFunction.CountIfs(Sheet5.Range("F:F"), .Range("B" & i), _
Sheet5.Range("G:G"), "A91.A", Sheet5.Range("H:H"), ">=" & CLng(.Range("N1").Value), Sheet5.Range("H:H"), _
"<=" & CLng(.Range("G7").Value))
Else
    .Range("D" & i).Value = 0
    .Range("E" & i).Value = WorksheetFunction.CountIfs(Sheet5.Range("F:F"), .Range("B" & i), _
Sheet5.Range("G:G"), "A91.A", Sheet5.Range("H:H"), ">=" & CLng(.Range("N1").Value), Sheet5.Range("H:H"), _
"<=" & CLng(.Range("G7").Value))
End If
  .Range("F" & i).Value = WorksheetFunction.CountIfs(Sheet5.Range("F:F"), .Range("B" & i), _
Sheet5.Range("G:G"), "A91.C", Sheet5.Range("H:H"), ">=" & CLng(.Range("A7").Value), Sheet5.Range("H:H"), _
"<=" & CLng(.Range("G7").Value))
    If .Range("F" & i).Value <> 0 Then
    .Range("G" & i).Value = WorksheetFunction.CountIfs(Sheet5.Range("F:F"), .Range("B" & i), _
Sheet5.Range("G:G"), "A91.C", Sheet5.Range("H:H"), ">=" & CLng(.Range("A7").Value), Sheet5.Range("H:H"), _
"<=" & CLng(.Range("G7").Value), Sheet5.Range("L:L"), "<=15")
    .Range("H" & i).Value = WorksheetFunction.CountIfs(Sheet5.Range("F:F"), .Range("B" & i), _
Sheet5.Range("G:G"), "A91.C", Sheet5.Range("H:H"), ">=" & CLng(.Range("N1").Value), Sheet5.Range("H:H"), _
"<=" & CLng(.Range("G7").Value))
Else
    .Range("G" & i).Value = 0
    .Range("H" & i).Value = WorksheetFunction.CountIfs(Sheet5.Range("F:F"), .Range("B" & i), _
Sheet5.Range("G:G"), "A91.C", Sheet5.Range("H:H"), ">=" & CLng(.Range("N1").Value), Sheet5.Range("H:H"), _
"<=" & CLng(.Range("G7").Value))
End If
.Range("K" & i).Value = WorksheetFunction.CountIfs(Sheet5.Range("F:F"), .Range("B" & i), _
Sheet5.Range("G:G"), "TV", Sheet5.Range("H:H"), ">=" & CLng(.Range("A7").Value), Sheet5.Range("H:H"), _
"<=" & CLng(.Range("G7").Value))
    If .Range("K" & i).Value <> 0 Then
    .Range("L" & i).Value = WorksheetFunction.CountIfs(Sheet5.Range("F:F"), .Range("B" & i), _
Sheet5.Range("G:G"), "TV", Sheet5.Range("H:H"), ">=" & CLng(.Range("A7").Value), Sheet5.Range("H:H"), _
"<=" & CLng(.Range("G7").Value), Sheet5.Range("L:L"), "<=15")
    .Range("M" & i).Value = WorksheetFunction.CountIfs(Sheet5.Range("F:F"), Sheet4.Range("B" & i), _
Sheet5.Range("G:G"), "TV", Sheet5.Range("H:H"), ">=" & CLng(.Range("N1").Value), Sheet5.Range("H:H"), _
"<=" & CLng(.Range("G7").Value))
Else
    .Range("L" & i).Value = 0
    .Range("M" & i).Value = WorksheetFunction.CountIfs(Sheet5.Range("F:F"), .Range("B" & i), _
Sheet5.Range("G:G"), "TV", Sheet5.Range("H:H"), ">=" & CLng(.Range("N1").Value), Sheet5.Range("H:H"), _
"<=" & CLng(.Range("G7").Value))
End If
i = i + 1
End With
Wend
End Sub
Có bạn gửi file với nói rõ điều kiện.
 
Upvote 0
Các anh chị có cách nào để codeCtrlF.png báo số lượng tìm được như hình không (phần khoanh tròn màu đỏ)
Em cảm ơn
 
Upvote 0
Có bạn gửi file với nói rõ điều kiện.
Dạ báo cáo của em như sau:
- Cột số mắc Nếu chẩn đoán là A91.A hoặc A91.C hoặc tử vong (mã ICD của sốt xuất huyết) và trong khoảng thời gian từ ngày đầu tháng đến ngày cuối tháng thì sẽ đếm tất cả các xã theo điều kiện để tính ca mắc trong tháng
- Cột <= 15 là tính các ca có tuổi nhỏ hơn <= 15 tuổi
- Cột cộng dồn là số ca mắc từ đầu năm đến hiện tại.
- Các cột khác tương tự. Thay đổi chổ chẩn đoán A91.A là SXHD thường và cảnh báo, A91.C là SXHD nặng, TV là số ca tử vong.
 

File đính kèm

Upvote 0
Dạ báo cáo của em như sau:
- Cột số mắc Nếu chẩn đoán là A91.A hoặc A91.C hoặc tử vong (mã ICD của sốt xuất huyết) và trong khoảng thời gian từ ngày đầu tháng đến ngày cuối tháng thì sẽ đếm tất cả các xã theo điều kiện để tính ca mắc trong tháng
- Cột <= 15 là tính các ca có tuổi nhỏ hơn <= 15 tuổi
- Cột cộng dồn là số ca mắc từ đầu năm đến hiện tại.
- Các cột khác tương tự. Thay đổi chổ chẩn đoán A91.A là SXHD thường và cảnh báo, A91.C là SXHD nặng, TV là số ca tử vong.
Bạn thử cái này nhé.Mình làm với 3 cột đầu.Bạn tìm hiểu mà hiểu được code thì chắc cũng nghĩ được làm các cột tiếp theo nhé.
Mã:
Sub baocaothang()
    Dim i As Long, lr As Long, arr, dic As Object, dk As String, ngaybd As Long, ngaykt As Long, kq() As Long, Data, T
    Set dic = CreateObject("scripting.dictionary")
    With Sheets("danh_sach")
         lr = .Range("B" & Rows.Count).End(xlUp).Row
         If lr < 2 Then Exit Sub
         arr = .Range("B2:K" & lr).Value
    End With
        For i = 1 To UBound(arr)
          If arr(i, 6) = "A91.A" Then
            dk = arr(i, 5)
            If Not dic.exists(dk) Then
               dic.Add dk, i
            Else
               dic.Item(dk) = dic.Item(dk) & "#" & i
            End If
          End If
        Next i
    With Sheets("SXHD_Thang")
         ngaybd = .Range("A7").Value2
         ngaykt = .Range("G7").Value2
         Data = .Range("B13:B26").Value
         ReDim kq(1 To UBound(Data), 1 To 11)
         For i = 1 To UBound(Data)
             dk = Data(i, 1)
             If dic.exists(dk) Then
                For Each T In Split(dic.Item(dk), "#")
                    If CLng(arr(T, 7)) >= ngaybd And CLng(arr(T, 7)) <= ngaykt Then
                       kq(i, 1) = kq(i, 1) + 1
                          If Year(Date) - Year(arr(T, 2)) <= 15 Then
                             kq(i, 2) = kq(i, 2) + 1
                          End If
                    End If
                    If Year(arr(T, 7)) = Year(Date) And CLng(arr(T, 7)) <= ngaykt Then
                       kq(i, 3) = kq(i, 3) + 1
                    End If
                Next
             End If
          Next i
         .Range("C13:M26").Value = kq
  End With
End Sub
 
Upvote 0
Bạn thử cái này nhé.Mình làm với 3 cột đầu.Bạn tìm hiểu mà hiểu được code thì chắc cũng nghĩ được làm các cột tiếp theo nhé.
Mã:
Sub baocaothang()
    Dim i As Long, lr As Long, arr, dic As Object, dk As String, ngaybd As Long, ngaykt As Long, kq() As Long, Data, T
    Set dic = CreateObject("scripting.dictionary")
    With Sheets("danh_sach")
         lr = .Range("B" & Rows.Count).End(xlUp).Row
         If lr < 2 Then Exit Sub
         arr = .Range("B2:K" & lr).Value
    End With
        For i = 1 To UBound(arr)
          If arr(i, 6) = "A91.A" Then
            dk = arr(i, 5)
            If Not dic.exists(dk) Then
               dic.Add dk, i
            Else
               dic.Item(dk) = dic.Item(dk) & "#" & i
            End If
          End If
        Next i
    With Sheets("SXHD_Thang")
         ngaybd = .Range("A7").Value2
         ngaykt = .Range("G7").Value2
         Data = .Range("B13:B26").Value
         ReDim kq(1 To UBound(Data), 1 To 11)
         For i = 1 To UBound(Data)
             dk = Data(i, 1)
             If dic.exists(dk) Then
                For Each T In Split(dic.Item(dk), "#")
                    If CLng(arr(T, 7)) >= ngaybd And CLng(arr(T, 7)) <= ngaykt Then
                       kq(i, 1) = kq(i, 1) + 1
                          If Year(Date) - Year(arr(T, 2)) <= 15 Then
                             kq(i, 2) = kq(i, 2) + 1
                          End If
                    End If
                    If Year(arr(T, 7)) = Year(Date) And CLng(arr(T, 7)) <= ngaykt Then
                       kq(i, 3) = kq(i, 3) + 1
                    End If
                Next
             End If
          Next i
         .Range("C13:M26").Value = kq
  End With
End Sub
Dạ cảm ơn bạn rất nhiều, mình chạy được code rồi, các cột khác mình tạo ra 2 Sub thay điều kiện chẩn đoán sau đó dùng Call để khởi chạy 3 sub cùng lúc.
 
Upvote 0
Upvote 0
Web KT

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

Back
Top Bottom