简体   繁体   中英

vba check if value exists in column h and if month of date in column m is this month?

I am trying to use vba to count the rows on sheet 2 ('logs') where column h matches the value entered into my cell on sheet 1 ('home'). I am doing this using the following code:

Dim iVal As Integer
    iVal = Application.WorksheetFunction.CountIf(Sheets("Logs").Columns("H"), Range("N10").Value)
    iVal2 = Application.WorksheetFunction.CountIf(Sheets("Logs").Columns("J"), Range("N20").Value)

If IsError(Application.Match(Range("N10").Value, Sheets("Logs").Columns("H"), 0)) Then
    MsgBox "No Match"
    Else
    MsgBox "Hi " & Range("N10").Value & "," & vbNewLine & vbNewLine & "Your department has requested " & iVal2 & " suppliers this month. You have " & 5 - iVal & " requests remaining for this month." & vbNewLine & vbNewLine & "Each department is allowed up to 5 new supplier requests per month.", vbOKOnly + vbInformation, "Important Notice!"
    Exit Sub
    End If

Now I want to add to my if statement and say only count the matching values against column h with the value entered in my cell on sheet 1 if the date in the same row in column M on sheet 2 contains the current month and year.

so for instance lets say todays month is 'October 2014' and column h contains the word 'apples' and in the same row in column M is '21/10/2014'.

If I then type 'apples' in my cell on sheet 1 then it will count 1 occurrence of the word apples for this month.

But if in my column h I have 'apples' and in column m is '21/09/2014' and todays month is October 2014 then this will not get counted as the month is not the current month.

Does anyone know a way I could do this? I am trying to surround my code with another if statement like so but I'm new to VBA and I don't think this is the way to go.

> If Month(Date) = Month(Sheets("Logs").Columns("M")) Then
>     MsgBox "Date now"
>     Else
>     MsgBox "Date not now"
>     End If

You don't strictly require VBA to accomplish this. Assuming a data grid of 99 rows on both Sheet1 and Sheet2, the following formula using native Excel functions will return a count for Sheet1!H1:99 matching N10 and Sheet2!M1:99 matching year and month of N20. =SUMPRODUCT((Sheet1!$H$1:$H$99=N10)*(TEXT(Sheet2!$M$1:$M$99,"yyyymm")=TEXT(N20,"yyyymm")))

Addendum: If you fully qualify the cell references, you can simply use square brackets to evaluate the formula like this:

Sub test()
    With ActiveSheet
        .Range("A1") = [=SUMPRODUCT((Sheet1!$H$1:$H$99=Sheet3!N10)*(TEXT(Sheet2!$M$1:$M$99,"yyyymm")=TEXT(Sheet3!N20,"yyyymm")))]
    End With
End Sub

Note that I've added the worksheet references for N10 and N20.

please try this as a possible solution that requires some 'finessing' eg error checking etc. - over to you!

For my testing, Sheets 'Home' and "Logs" as below, the Date cells are formatted as Date. If you require different date formats on different sheets then this is for you to finesse. Assign the button to the code called 'CountMatches' (below). This approach uses AutoFilter. Most of the parameters can easily be set for you to make adjustments to your situation.

The Sheets

在此处输入图片说明

在此处输入图片说明

The Code

Sub CountMatches()
Dim wsLogs As Worksheet, wsHome As Worksheet
Dim lstrow As Long, lendrow As Long, lstcol As Long, lendcol As Long
Dim crit1row As Long, crit1col As Long, crit2row As Long, crit2col As Long
Dim rsltRow As Long, rsltCol As Long, rslt As Long
Dim fndrng As Range

Set wsLogs = Sheets("Logs")
Set wsHome = Sheets("Home")
lstrow = 1
lstcol = 8: lendcol = 13    'col H-M
crit1row = 3: crit2row = 3
crit1col = 3: crit2col = 5
rsltRow = 3: rsltCol = 7

'clear autofilter
wsLogs.AutoFilterMode = False

    With wsLogs
        lendrow = .Cells(Rows.Count, lstcol).End(xlUp).Row
            With .Range(.Cells(lstrow, lstcol), .Cells(lendrow, lendcol))
                crit1 = wsHome.Cells(crit1row, crit1col).Value
                crit2 = wsHome.Cells(crit2row, crit2col).Value
                crit2 = DateSerial(Year(crit2), Month(crit2), Day(crit2))
                'set autofilter
                .AutoFilter
                .AutoFilter Field:=1, Criteria1:=crit1
                .AutoFilter Field:=6, Criteria1:="=" & crit2
                    With wsLogs.AutoFilter.Range
                        Set fndName = .SpecialCells(xlCellTypeVisible)
                    End With
            End With

            With .AutoFilter.Range
                 On Error Resume Next
                   Set fndrng = .Offset(1, 0).Resize(.Rows.Count - 1, 6) _
                       .SpecialCells(xlCellTypeVisible)
                       rslt = .Columns(1).SpecialCells(xlCellTypeVisible).Count - 1
                       'MsgBox .Columns(1).SpecialCells(xlCellTypeVisible).Count - 1
                 On Error GoTo 0
            End With

            With wsHome
                 .Range(.Cells(rsltRow, rsltCol), .Cells(rsltRow, rsltCol)) = rslt
            End With

    wsLogs.AutoFilterMode = False

    End With

End Sub

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM