Excel VBA: Using Variables in CountIf function - excel

I can't overcome this seemingly simple issue involving the use of a variable in a countif function - hoping you guys can help. I'm looping through a list of data that spans 2006 through 2024, using the if statements to determine the beginning and the end of my search range, which will be used in the countif function at the end of the code. The do/loop section appropriately defines the ranges, however I receive errors when the macro attempts to place the countif function in the designated cell using the variable containing the search range. Here's my code:
Dim Year As Integer
Dim Month As Integer
Year = InputBox("Enter the Current Year", "Choose Year for Analysis", "Type your desired year here")
If Len(Year) = 0 Then
MsgBox "No year chosen, this macro will now end)"
Exit Sub
End If
Month = InputBox("Enter the first # that corresponds with the first month you would like to review", "Starting Month", "Enter the # that corresponds with your desired month here")
If Len(Year) = 0 Then
MsgBox "No month chosen, this macro will now end)"
Exit Sub
End If
Dim SearchStart As Range
Dim SearchEnd As Range
Dim searchrange As Range
'standard
Range("L2").Select
Do Until ActiveCell.Value = Year And ActiveCell.Offset(0, 1).Value > Month + 1
If ActiveCell.Value = Year And ActiveCell.Offset(-1, 0).Value = Year And ActiveCell.Offset(0, 1).Value = Month And ActiveCell.Offset(-1, 1).Value = Month Then
ActiveCell.Offset(1, 0).Select
Else
If ActiveCell.Value = Year And ActiveCell.Offset(-1, 0).Value = Year And ActiveCell.Offset(0, 1).Value = Month + 1 And ActiveCell.Offset(-1, 1).Value = Month + 1 Then
ActiveCell.Offset(1, 0).Select
Else
If ActiveCell.Value = Year And ActiveCell.Offset(-1, 0).Value = Year And ActiveCell.Offset(0, 1).Value = Month + 1 And ActiveCell.Offset(-1, 1).Value = Month Then
ActiveCell.Offset(1, 0).Select
Else
If Not ActiveCell.Value = Year And ActiveCell.Offset(0, 1).Value = Month And SearchStart Is Nothing Then
ActiveCell.Offset(1, 0).Select
Else
If ActiveCell.Value = Year And ActiveCell.Offset(0, 1).Value = Month And Not IsEmpty(SearchStart) Then
ActiveCell.Offset(0, -1).Select
Set SearchStart = Selection
ActiveCell.Offset(1, 1).Select
End If
End If
End If
End If
End If
If ActiveCell.Value < Year Then
ActiveCell.Offset(1, 0).Select
Else
If ActiveCell.Value < Year And ActiveCell.Offset(0, 1).Value < Month Then ActiveCell.Offset(1, 0).Select
If ActiveCell.Value = Year And ActiveCell.Offset(0, 1).Value < Month Then ActiveCell.Offset(1, 0).Select
End If
Loop
ActiveCell.Offset(-1, -1).Select
Set SearchEnd = ActiveCell
Range(SearchStart.Address, SearchEnd.Address).Select
Set searchrange = Selection
'formula to find: Current month QTY & next month QTY
Range("z2").Select
Selection.FormulaR1C1 = "=COUNTIF(" & searchrange.Address & ",RC[-1])"

In this block of code you are mixing how the ranges are addressed:
Selection.FormulaR1C1 = "=COUNTIF(" & searchrange.Address & ",RC[-1])"
You need to use the R1C1 syntax:
Selection.FormulaR1C1 = "=COUNTIF(" & searchrange.Address(ReferenceStyle:=xlR1C1) & ",RC[-1])"
FYI, you should avoid using Select, so you can replace:
Range("z2").Select
Selection.FormulaR1C1 = "=COUNTIF(" & searchrange.(AddressReferenceStyle:=xlR1C1) & ",RC[-1])"
With:
Range("z2").FormulaR1C1 = "=COUNTIF(" & searchrange.Address(ReferenceStyle:=xlR1C1) & ",RC[-1])"

Related

else if statement for check in check out sheet vba not working

I have an excel sheet in which lies a data entry form and a check in check out list. I have a macro set up to search for the entry, and if it doesnt exist, make a new entry with a checkout time, if it does exist, it checks it back in with a time. My issue lies when I try to check out an entry that already exists. The code just updates the check in time. Ive added an elseif statement into the code but it doesnt seem to do anything. If anyone could help me figure out why itd be much appreciated.
Sub inout()
Dim barcode As String
Dim rng As Range
Dim rownumber As Long
barcode = Worksheets("Sheet1").Cells(2, 2)
Set rng = Sheet1.Columns("a:a").Find(What:=barcode, _
LookIn:=xlFormulas, LookAt:=xlWhole, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)
If rng = True Or ActiveCell.Offset(0, 2).Value = True Then
rownumber = rng.Row
Worksheets("Sheet1").Cells(rownumber, 1).Select
ActiveCell.Offset(0, 2).Clear
ActiveCell.Offset(0, 1).Select
ActiveCell.Value = Date & " " & Time
ActiveCell.NumberFormat = "m/d/yyyy h:mm AM/PM"
Worksheets("Sheet1").Cells(2, 2) = ""
Cells(2, 2).Select
ElseIf rng Is Nothing Then
ActiveSheet.Columns("a:a").Find("").Select
ActiveCell.Value = barcode
ActiveCell.Offset(0, 1).Select
ActiveCell.Value = Date & " " & Time
ActiveCell.NumberFormat = "m/d/yyyy h:mm AM/PM"
Worksheets("Sheet1").Cells(2, 2) = ""
ActiveCell.Offset(0, 3).Select
ElseIf rng = True Then
rownumber = rng.Row
Worksheets("Sheet1").Cells(rownumber, 1).Select
ActiveCell.Offset(0, 2).Select
ActiveCell.Value = Date & " " & Time
ActiveCell.NumberFormat = "m/d/yyyy h:mm AM/PM"
Worksheets("Sheet1").Cells(2, 2) = ""
rng.Offset(, 1).Clear
ActiveCell.Offset(0, 2).Value = "TOOL CRIB"
Cells(2, 2).Select
End If
End Sub

VBA code to insert value in Excel based on values in another sheet

I am trying to insert program names into "F Column" according to the "switchtime" provided in the previous column. The "switch time" is compared with the master sheet(sheet1) to see what program was running when the switch happened.
These are the two sheets used.
But when running I get error message saying "SELECT Method of Range Class Failed".
Sub Protest()
Dim chno, swtime, stime, ftime As Integer, swprog As String
Sheets("Sheet2").Select
Range("F1").Select
Do Until Selection.Offset(0, -3).Value = ""
chno = Selection.Offset(0, -3).Value
swtime = Selection.Offset(0, -1).Value
If chno = "1" Then
Sheets("Sheet1").Range("E4").Select
Do Until Selection.Offset(0, 0).Value = ""
stime = Selection.Offset(0, 0).Value
ftime = Selection.Offset(0, 1).Value
If swtime >= stime And swtime <= ftime Then
swprog = Selection.Offset(0, -1).Value
End If
Selection.Offset(1, 0).Select
Loop
End If
If chno = "2" Then
Sheets("Sheet1").Range("I4").Select
Do Until Selection.Offset(0, 0).Value = ""
stime = Selection.Offset(0, 0).Value
ftime = Selection.Offset(0, 1).Value
If swtime >= stime And swtime <= ftime Then
swprog = Selection.Offset(0, -1).Value
End If
Selection.Offset(1, 0).Select
Loop
End If
If chno = "3" Then
Sheets("Sheet1").Range("M4").Select
Do Until Selection.Offset(0, 0).Value = ""
stime = Selection.Offset(0, 0).Value
ftime = Selection.Offset(0, 1).Value
If swtime >= stime And swtime <= ftime Then
swprog = Selection.Offset(0, -1).Value
End If
Selection.Offset(1, 0).Select
Loop
End If
Selection.Value = swprog
Selection.Offset(1, 0).Select
Loop
Range("A1").Select
End Sub

Find The Max Value And From A Column That Also Contains Text

I'm trying to create a macro that would find the maximum numerical value in a column (which also contains text) and inserts a new row with that value +1.
For some reason it won't work and just keeps the original number, it also messes up the conditional formatting I have in column D even if that column is locked.
Sub_Move()
Set wk1 = Sheet1
Set wk2 = Sheet4
Set wk3 = Sheet5
Dim mynumber As Long
Application.ScreenUpdating = False
Sheet1.Unprotect
Sheet4.Unprotect
Sheet5.Unprotect
mynumber = 1
'Move-Characterisation'
Worksheets("Characterisation").Activate
For i = 1000 To 15 Step -1
If Range("W" & i).Value = "Completed" Then
Worksheets("Burn").Activate
Range("B15:W15").Select
Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
Range("B15:W15").Interior.ColorIndex = xlNone
End If
Worksheets("Characterisation").Activate
If Range("W" & i).Value = "Completed" Then
Range("W" & i).Select
Range("W" & i).Value = "Delete"
Range(ActiveCell, ActiveCell.Offset(0, -21)).Select
Selection.Copy
Worksheets("Burn").Activate
Range("B15").Select
ActiveSheet.Paste
Range("W15").ClearContents
**MaxVal1 = Application.WorksheetFunction.Max(wk2.Range("D15:D1000"))
Range("D15").Value = MaxVal1 + 1**
End If
Worksheets("Characterisation").Activate
If Range("W" & i).Value = "Delete" Then
Range("W" & i).Select
Range(ActiveCell, ActiveCell.Offset(0, -21)).Select
Selection.Delete Shift:=xlUp
End If
Next
I would be grateful for any help.

Adding Columns to paste date and skill from table vba Excel

I have several tables pasted one after another, I am trying to add two extra columns, one for the skill name and one for the date. When i run this code, the columns are added and I can see the pointer going to each cell, but it is not assigning any values. I will appreciate your suggestions on this code.
Dim date_var As String
Dim skill_var As String
Dim msg_var As Integer
Sub Add_Date_Skill()
ThisWorkbook.ActiveSheet.Range("A1").Select
ActiveCell.EntireColumn.Insert
ActiveCell.EntireColumn.Insert
ThisWorkbook.ActiveSheet.Range("C2").Select
Do While Not IsEmpty(ActiveCell.Value)
If ActiveCell.Value = "Date" Then
ActiveCell.Offset(0, 1).Select
Let date_var = ActiveCell.Value
ActiveCell.Offset(0, -1).Select
ElseIf ActiveCell.Value = "Split/Skill" Then
ActiveCell.Offset(0, 1).Select
Let skill_var = ActiveCell.Value
ActiveCell.Offset(0, -1).Select
Else
ActiveCell.Offset(0, -2).Select
ActiveCell.Value = skill_var
ActiveCell.Offset(0, 1).Select
ActiveCell.Value = date_var
ActiveCell.Offset(0, 1).Select
End If
ActiveCell.Offset(1, 0).Select
Loop
End Sub
Solved, the Date and Split/Skills have a Colon (:) at the end!

Get autofill macro to stop if no rows to autofill to

I have a spreadsheet that pulls certain items out of a database by an autofilter macro and puts them into different sections. I have formulas that go in and are autofilled down to every line in each section. The problem I am running into is if a section only has one line my macro will debug. Below is my code that inserts the formulas and autofills them down. The very last row is the autofill macro and the one I need help with. Can someone please provide me an override that says if there is no lines to autofill to just move on to the next step. I'm not sure how this code would go. Thanks
'To insert formulas
ActiveCell.Offset(0, 1).Select
ActiveCell.FormulaR1C1 = "=IF(RC5<'Data Entry'!R2C2,""*"","""")"
ActiveCell.Offset(0, 1).Select
ActiveCell.FormulaR1C1 = "=IF(RC18=TRUE,IFERROR(VLOOKUP(RC2,Database!C[-2]:C[9],11,FALSE),""""),0)"
ActiveCell.Offset(0, 1).Select
ActiveCell.FormulaR1C1 = "=IFERROR(VLOOKUP(RC2,Database!C[-3]:C[8],10,FALSE),"""")"
ActiveCell.Offset(0, 1).Select
ActiveCell.FormulaR1C1 = "=IFERROR((VLOOKUP(RC9,Pull!C1:C5,4,FALSE))*RC4,"""")"
ActiveCell.Offset(0, 1).Select
ActiveCell.FormulaR1C1 = "=IFERROR((VLOOKUP(RC9,Pull!C1:C5,5,FALSE))*RC4,"""")"
ActiveCell.Offset(0, 1).Select
ActiveCell.FormulaR1C1 = "=IFERROR(SUM(RC4,RC6:RC7),"""")"
ActiveCell.Offset(0, 1).Select
ActiveCell.FormulaR1C1 = "=IFERROR(VLOOKUP(RC2,Database!C[-7]:C[4],6,FALSE),"""")"
ActiveCell.Offset(0, 1).Select
ActiveCell.FormulaR1C1 = "=IF(RC18=TRUE,IFERROR(VLOOKUP(RC9,'Pull'!C1:C5,2,FALSE),""""),"""")"
ActiveCell.Offset(0, 1).Select
ActiveCell.FormulaR1C1 = "=IFERROR(RC8*RC10,"""")"
ActiveCell.Offset(0, 1).Select
ActiveCell.FormulaR1C1 = "=IFERROR(RC8+RC11,"""")"
ActiveCell.Offset(0, 1).Select
ActiveCell.FormulaR1C1 = "=IFERROR(RC16*R9C13,"""")"
ActiveCell.Offset(0, 1).Select
ActiveCell.FormulaR1C1 = "=IF(RC18=TRUE,IFERROR(VLOOKUP(RC9,'Pull'!C1:C5,3,FALSE),""""),"""")"
ActiveCell.Offset(0, 1).Select
ActiveCell.FormulaR1C1 = "=IFERROR(RC16*RC14,"""")"
ActiveCell.Offset(0, 1).Select
ActiveCell.FormulaR1C1 = "=IFERROR(RC12/(1-R9C13-RC14),"""")"
Range(Cells(Selection.Row, 3), Cells(Selection.Row, 17)).AutoFill Destination:=Range(Cells(Selection.Row, 3), "Q" & Range("B" & Rows.Count).End(xlUp).Row)
I'd set a LastRow variable, calculated the way you already do, and test whether it's greater than the Selection row:
Dim LastRow as Long
LastRow = ActiveSheet.Range("B" & Rows.Count).End(xlUp).Row
...
If LastRow > Selection.Row Then
Range(Cells(Selection.Row, 3), Cells(Selection.Row, 17)).AutoFill Destination:=Range(Cells(Selection.Row, 3), "Q" & LastRow)
EndIf
By the way, if you search on "VBA avoid Select statements" you'll get some info on why that's a good idea and how to do it. In this case I'd set a CellWithFormula variable at the beginning of the code:
Dim CellWithFormula as Excel.Range
Set CellWithFormula = Activcell
CellWithFormula.FormulaR1C1 = "=IF(RC5<'Data Entry'!R2C2,""*"","""")"
Set CellWithFormula = CellWithFormula.Offset(0, 1)
... and so on.

Resources