Moving up to a certain cell range - vba

I am trying to run a program that allows me to see what rooms in a college are free at a certain time in Microsoft excel.
The problem I am having is after I identify a empty class slot :
how doIi code it to go back up into the names of all the class rooms (All names are at Row 2)
and store the value of this.
I have tried offsetting but that wouldn't work for me.
I have added the Sample Data for further clarification
Public Sub EXq3()
Dim rnR1 As Range, roomNum As Integer
Const rooms = 13 ' Counter amount
Set rgR1 = ActiveCell.Offset(0, 1)
timeSolt = InputBox("What time") ' asks user what time to enter
Cells.find(What:=timeSolt, After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=False).Activate ' search and find code
For counter = 1 To rooms
If rgR1.Value = "" Then roomNum = rgR1.Offset(Range(2, rgR1.Value)) ' attempt at getting it to go to range 2
rgR1.Activate
Set rgR1 = rgR1.Offset(0, 1)
Next counter
MsgBox roomNum
End Sub

You probably by "go to range 2" mean "go to row 2", am I right? If yes, this is your solution:
For counter = 1 To rooms
If rgR1.Value = "" Then
roomNum = Cells(2, rgR1.Column).Value
End If
rgR1.Activate
Set rgR1 = rgR1.Offset(0, 1)
Next counter
EDIT
Ok, so I assume that you have some time options in column A, and some values for Room 1 in column B, Room 2 in column C etc. I have refactored your code to get rid of moving active cell. It is finding some time in column A and checking if there are some empty cells in row with this time option, and returns messages with numbers of this rooms.
My test sheet:
Code:
Public Sub EXq3()
Dim rnR1 As Range, roomNum As String, rooms As Integer Dim timeSolt As String
rooms = 13 ' Counter amount timeSolt = InputBox("What time") ' asks user what time to enter
Set rnR1 = ActiveSheet.Columns("A:A").Find(What:=timeSolt, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False) ' search and find code
If rnR1 Is Nothing Then
MsgBox "Something is wrong with Input."
Else
For col = 2 To rooms + 1
If Cells(rnR1.Row, col).Value = "" Then
roomNum = Cells(2, col).Value
MsgBox roomNum
End If
Next col
End If
End Sub
So, i. e. when you type 17 in pop-up window, the result would be "Room 4" and "Room 10".

There is no need to Set rgR1 = ActiveCell.Offset(0, 1) , you can just search for the TimeSlot entered at the InputBox throughout your worksheet.
Also, it's better to stay away from Activate and ActiveCell and instead use referenced Ranges.
Since there is a possibility you have a few available room for a certain time, you need to store it as an array, and raise the index of rooms found on every match of ="".
There are more explanations inside the code comments below.
Code
Option Explicit
Public Sub EXq3()
Dim rnR1 As Range, roomNum As Variant, TimeSlot
Dim FindRng As Range, i As Integer, Counter As Integer
Const rooms = 13 ' Counter amount
ReDim roomNum(1 To 1000) ' init Rooms avaialable array to a large size
i = 1 '<-- reset Rooms Array index
TimeSlot = InputBox("What time") ' asks user what time to enter
Set FindRng = Cells.Find(What:=TimeSlot, After:=Range("A1"), LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=False) ' search and find TimeSlot
If Not FindRng Is Nothing Then '<-- was able to find the timeslot in the worksheet
For Counter = 1 To rooms
If Cells(FindRng.Row, Counter + 1).Value = "" Then '<-- add 1 to counter since starting from Column B
roomNum(i) = Cells(2, Counter + 1).Value '<-- save room number inside the array
i = i + 1
End If
Next Counter
ReDim Preserve roomNum(1 To i - 1) ' <-- resize array back to number of available rooms found
' loop through all available rooms in the array, and show a msgbox for each one
For i = 1 To UBound(roomNum)
MsgBox "Room number " & roomNum(i) & " is available at " & TimeSlot
Next i
Else '<-- could bot find the timeslot in the worksheet
MsgBox "Couldn't find " & TimeSlot & " inside the worksheet!"
End If
End Sub

you could try this:
Public Sub EXq3()
Dim rnR1 As Range
Dim rooms As Integer
Dim timeSolt As String, roomNum As String
rooms = 13 ' Counter amount
With ActiveSheet
Do
timeSolt = Application.InputBox("What time", "Input time", Type:=2)
If timeSolt = CStr(False) Then Exit Sub '<--| exit if user cancels the dialogbox
Set rnR1 = .Columns("A:A").SpecialCells(XlCellType.xlCellTypeConstants, xlTextValues).Find(What:=timeSolt, LookIn:=xlValues, LookAt:=xlWhole, MatchCase:=False, SearchFormat:=False) ' search and find code
If Not rnR1 Is Nothing Then Exit Do
MsgBox timeSolt & " is not a vaild time" & vbCrLf & vbCrLf & "please try again"
Loop
With .Range(rnR1.Offset(, 1), .Cells(rnR1.Row, .Columns.count).End(xlToLeft))
If WorksheetFunction.CountBlank(.Cells) = 0 Then
MsgBox "Sorry! No rooms left for the input time"
Else
roomNum = .Parent.Cells(2, .SpecialCells(xlCellTypeBlanks).Cells(1, 1).Column)
MsgBox "First room available at " & timeSolt & " is room " & roomNum
End If
End With
End With
End Sub

Related

VBA I want to compare windows username with a named range and return the cell reference so I can replace with a new value

in the below code I have a named ranges called "currentOwn" and "authHolders".
What I am trying to do is use the function to find the windows username which works. I then want to compare this to the named range "currentOwn" and give me a cell reference within that range that I can then use to replace with another value.
This is a system that allows a user to hand over keys to another user, I only want the range to include people who have key ownership, because there is only a fixed amount of keys.
Option Explicit
Public Function WindowsUserName()
' Function to return the username of whoever is logged in
Dim Position As Integer, FirstName As String, LastName As String, OldUsername As String
OldUsername = LCase(Environ$("UserName"))
Position = InStr(1, OldUsername, ".")
If Position = 1 Or Position = Len(OldUsername) Then
WindowsUserName = OldUsername
Else
FirstName = UCase(Mid(OldUsername, 1, 1)) & Mid(OldUsername, 2, Position - 2)
LastName = UCase(Mid(OldUsername, Position + 1, 1)) & Mid(OldUsername, Position + 2, Len(OldUsername) - Position - 1)
WindowsUserName = FirstName & " " & LastName
End If
End Function
Private Sub CommandButton1_Click()
Dim newHolder As Variant, currentHold As Variant, handOverTo As Variant, i As Integer, rng As Range
currentHold = WindowsUserName
newHolder = Sheets("tools").Range("K1")
If Range("currentOwn").Find(newHolder, , Excel.xlValues) Is Nothing Then
If Range("authHolder").Find(newHolder, , Excel.xlValues) Is Nothing Then
MsgBox ("Not an authorised key holder")
End If
Else
MsgBox ("This person currently holds a set of keys please select another user")
Exit Sub
End If
For i = 1 To 500
Set rng = Range("currentOwn")
If rng.Cells(i).Find(currentHold, , Excel.xlValues) = True Then
MsgBox ("Found value on row " & i)
Exit Sub
End If
Next i
End Sub
the loop at the bottom is my attempt to try and get it to show me the cell reference. However this does not work I would like to use this value to set an Active cell then I can replace value with another.
Regards,
Hello I have now fixed this using the below instead of a loop thanks for your help, however I have a query on this code now how can I make this find the match but only select the one where the date column ("Match".offset,3)="blank"
If Trim(currentHold) <> "" Then
With Sheets("currentHolders").Range("currentOwn")
Set rng = .Find(What:=currentHold, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not rng Is Nothing Then
Application.Goto rng, True
MsgBox (rng)
End If
End With
End If
Regards,

Appending to a cell value in VBA

I'm sure there's an obvious answer here, but I'm stuck. This part in particular is throwing 424: Object Required. The really odd part, to me, is that it does successfully append 0s to the column, but then halts, and doesn't continue.
If cellLen < 9 Then
Set C.Value = 0 & C.Value
End If
The rest of the code is below for clarity. In case it's not clear, this is the intended code flow:
Grabs named fields
Copies those columns to a new sheet
Renames them and deletes the original sheet
Creates some new sheets for use with a different script
Searches for missing leading 0s in a specific column
Adds them back in (this is the part the breaks)
Deletes rows where that specific column's cell value is 0
Pulls that cleaned-up column out to a new file and saves it
Sub Cleanup_Mapwise_Import()
Dim targetCols As Variant
Dim replColNames As Variant
Dim index As Integer
Dim found As Range
Dim counter As Integer
Dim headerIndex As Integer
Dim question As Integer
Dim rowCount As Variant
Dim colNum As Variant
Dim colLetter As Variant
Dim C As Range
Dim cellLen As Integer
' Add or remove fields to be copied here
targetCols = Array("gs_account_number", "gs_meter_number", "gs_amr_identification", _
"gs_amr_phase", "gs_city", "Name", "Phase", _
"gs_rate_schedule", "gs_service_address", _
"gs_service_map_location", "gs_service_number")
' Put the same fields from above in the desired order here, with the desired name
replColNames = Array("Acct #", "Meter #", "AMR ID", "AMR Phase", "City", _
"Name", "Phase", "Rate", "Address", "Srv Map Loc", "Srv Num")
counter = 1
ActiveSheet.Range("A1").Select
' This counts the number of columns in the source array and sets the index to that value
For index = LBound(targetCols) To UBound(targetCols)
Set found = Rows("1:1").Find(targetCols(index), LookIn:=xlValues, LookAt:=xlWhole, _
SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:=False)
' This is basically an insertion sort, and ends up with the columns in A:K
If Not found Is Nothing Then
If found.Column <> counter Then
found.EntireColumn.Cut
Columns(counter).Insert shift:=xlToRight
Application.CutCopyMode = False
End If
counter = counter + 1
End If
Next index
' There is a more dynamic way of doing this, using index
' As it is, replace A:K with the range of actual data
' PROTIP: targetCols is 1-indexed, and has 11 entries -->
' A:K encompasses that entire array -->
' Add/subtract 1 for each entry you add/remove
Range("A:K").Cut
Set TargetSheet = Sheets.Add(After:=Sheets(Sheets.Count))
TargetSheet.Name = "Contributors"
Range("A:K").Insert
question = MsgBox("Do you want to delete the original sheet?", vbYesNo + vbQuestion, "Delete Sheet")
If question = vbYes Then
Sheets(1).Activate
Sheets(1).Delete
Else
End If
Sheets.Add.Name = "Data"
Sheets("Contributors").Move After:=Sheets("Data")
Sheets.Add.Name = "Graph"
Sheets("Graph").Move After:=Sheets("Contributors")
Sheets("Data").Activate
Range("A1").Value = "Date/Time"
Range("B1").Value = "kW"
Range("C1").Value = "Amps"
' Yes, counter is 0-indexed here, and 1-indexed previously
' headerIndex does an absolute count of 0 To # targetCols, whereas index is relative
' If you change these, there is a non-zero chance that the For will throw an error
counter = 0
Sheets("Contributors").Activate
ActiveSheet.Range("A1").Select
For headerIndex = 0 To (UBound(targetCols) - LBound(targetCols))
ActiveCell.Value = replColNames(counter)
' If you don't use a Range, it fits columns based on headers, which isn't large enough
' A1:Z500 is a big enough sample to prevent that
ActiveCell.Range("A1:Z500").Columns.AutoFit
ActiveCell.Offset(0, 1).Select
counter = counter + 1
Next headerIndex
' Find column number with meters numbers, then assign its corresponding letter value
colNum = Application.WorksheetFunction.Match("Meter #", Range("A1:ZZ1"), 0)
colLetter = (Split(Cells(, colNum).Address, "$")(1))
rowCount = Range(colLetter & Rows.Count).End(xlUp).Row
'Range(colLetter & "2:" & colLetter & rowCount).Select
'Selection.SpecialCells(xlCellTypeBlanks).Select
'Selection.Delete Shift:=xlUp
' Meter numbers are 9 digits, so if one is shorter, assume a trimmed leading 0 and append it
For Each C In Range(colLetter & "2:" & colLetter & rowCount).Cells
' If cell type isn't set to text, the 0s will be non-visible, which while not an issue for the CSV, is confusing
' Note that this does not persist, as CSVs have no way of saving Excel's formatting
C.NumberFormat = "#"
cellLen = Len(C.Value)
If C.Value = "0" Or cellLen = 0 Then
C.Delete shift:=xlUp
End If
If cellLen < 9 Then
Set C.Value = 0 & C.Value
End If
Next C
question = MsgBox("Do you want to create a CSV file with meter numbers for use with MDMS?", vbYesNo + vbQuestion, "MDMS File")
If question = vbYes Then
' Call CopyMeters for use with MDMS
Sheets("Contributors").Activate
CopyMeters
Else
End If
End Sub
Sub CopyMeters()
Dim index As Integer
Dim fileSaveName As Variant
Dim rowCount As Variant
Dim colNum As Variant
Dim colLetter As Variant
Dim cellLen As Integer
colNum = Application.WorksheetFunction.Match("Meter #", Range("A1:ZZ1"), 0)
colLetter = (Split(Cells(, colNum).Address, "$")(1))
rowCount = Range(colLetter & Rows.Count).End(xlUp).Row
MsgBox ("Filename will automatically be appended with ""Meter List""")
fileSaveName = Split(ActiveWorkbook.Name, ".")
fileSaveName = fileSaveName(LBound(fileSaveName)) & " Meter List"
'For Each C In Range(colLetter & "2:" & colLetter & rowCount)
' C.NumberFormat = "#"
' cellLen = Len(C)
' If C.Value = "0" Or cellLen = 0 Then
' C.Delete shift:=xlUp
' End If
' If cellLen < 9 And cellLen <> 0 Then
' C.Value = "0" & C.Value
' End If
'Next C
Range(colLetter & "1:" & colLetter & rowCount).EntireColumn.Copy
Set newBook = Workbooks.Add
newBook.Worksheets("Sheet1").Range("A1").PasteSpecial (xlPasteAll)
Selection.Replace What:="0", Replacement:="", LookAt:=xlWhole, _
SearchOrder:=xlByColumns, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
Selection.Columns.AutoFit
newBook.SaveAs Filename:=fileSaveName, FileFormat:=xlCSV, CreateBackup:=False
End Sub
The error message is telling you that C is not an object. Therefore, you do not need the Set statement. Change your code to this:
If cellLen < 9 Then
C.Value = 0 & C.Value
End If
Why not just change the numberformat on the range? Or use a function for the value? A function would be something like
Public Function FormatValues(ByVal Input as String) as String
If Input <> vbNullString Then FormatValues = Format(Input, "000000000")
End Function
And it would be called like:
C.Value = FormatValues(C.Value)
But, if you're strictly interested in what the value looks like, and not as much as what the value is (since the leading zero will only be retained for strings) you could do something like this:
Public Sub FixFormats()
ThisWorkbook.Sheets("SomeSheet").Columns("A").NumberFormat = "000000000")
End Sub
This would format Column A of Worksheet "SomeSheet" to be of the format "0000000" which means numbers would look like "000000001", "000000002" so on so forth, regardless of whether something like "2" was actually entered.

Excel VBA: FindNext in nested loops

I am trying to create a loop using the .Find function within another loop which is already using .Find. I want to search for strings that I have saved in an array.
For example, these are the string values saved in the array strItem in Sheet1.
"unit1", "unit2", "unit3"
I would like to search them one by one from Sheet2. Sheet2 looks like this:
unit1
unit2
unit3
unit1.pdf
text1
subject1
subject2
subject3
text2
=========
unit2.pdf
text1
subject1
subject2
subject3
text2
=========
unit3.pdf
text1
subject1
subject2
subject3
text2
=========
After searching for "unit1.pdf", I search all cells below it for "subject", and get cell values of subject1, 2, and 3. The search for "subject" cells should stop at the next cell which contains "====".
Next I search for "unit2", and if found search for "subject" cells under it as before. Again, stop at the cell containing "====". And so on.
In my code, what I am trying to do was
Search for the string "unit".
Use its .row as the range to start searching for "subject".
Return all subjects until the cell contains "====". This is a part of my code that I can't really make to work.
Code:
Wb2.Sheets("Sheet2").Activate
With Wb2.Sheets("Sheet2").Range("A1:A1048575")
For Each strItem In arrExcelValues
myStr = strItem & ".pdf"
Set p = .Find(What:=myStr, LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False)
If Not p Is Nothing Then
firstAddress = p.Address
Do
myStr2 = p.row
strStart = "A" & myStr2
strEnd = "A1048575"
With Wb2.Sheets("Sheet2").Range(strStart, strEnd)
Set p1 = .Find(What:="Subject", LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False)
If Not p1 Is Nothing Then
firstAddress = p1.Address
Do
myStr2 = myStr2 + 1
If p1.Offset(myStr2, 0).Value = "====" Then
Exit Do
Else
MsgBox p1.Value & strItem
End If
Set p1 = .FindNext(p1)
Loop While Not p1 Is Nothing And p1.Address <> firstAddress
Else
MsgBox "Not found"
End If
End With
Set p = .FindNext(p)
Loop While Not p Is Nothing And p.Address <> firstAddress
Else
MsgBox "Not found"
End If
Next
End With
You're not far off, but there are a couple of things to think about:
It seems you know the order of your data, you can use this to make life easier than using Find on the entire column.
You cannot use nested With statements unless you are going further into the child elements. It is good you are trying to fully qualify things, but be careful. For instance,
' This is okay
With ThisWorkbook.Sheets("Sheet2")
With .Range("A1")
MsbBox .Value
End With
With .Range("A2")
MsgBox .Value
End With
End With
' This is not okay, and present in your code
With ThisWorkbook.Sheets("Sheet2").Range("A1")
MsgBox .Value
With ThisWorkbook.Sheets("Sheet2").Range("A2")
Msgbox .Value
End With
End With
I have taken the ideas in your code, and re-written it to be a bit clearer, and hopefully achieve what you want. See the comments for details:
Dim Wb2 As Workbook
Dim lastRow As Long
Set Wb2 = ThisWorkbook
' Get last used row in sheet, so search isn't on entire column
lastRow = Wb2.Sheets("Sheet2").UsedRange.Rows.Count
' Set up array of "unit" values
Dim arrExcelValues() As String
arrExcelValues = Split("unit1,unit2,unit3", ",")
' Declare variables
Dim pdfCell As Range
Dim eqCell As Range
Dim eqRow As Long
eqRow = 1
Dim subjCell As Range
Dim strItem As Variant
' Loop over unit array
With Wb2.Sheets("Sheet2")
For Each strItem In arrExcelValues
' Find the next "unitX.pdf" cell after the last equals row (equals row starts at 1)
Set pdfCell = .Range("A" & eqRow, "A" & lastRow).Find(what:=strItem & ".pdf", lookat:=xlPart)
If Not pdfCell Is Nothing Then
' pdf row found, find next equals row, store row value or use last row
Set eqCell = .Range("A" & pdfCell.Row, "A" & lastRow).Find(what:="====", lookat:=xlPart)
If eqCell Is Nothing Then
eqRow = lastRow
Else
eqRow = eqCell.Row
End If
' Loop through cells between pdf row and equals row
For Each subjCell In .Range("A" & pdfCell.Row, "A" & eqRow)
' If cell contents contain the word "subject" then do something (display message)
If InStr(UCase(subjCell.Value), "SUBJECT") > 0 Then
MsgBox "Subject: " & subjCell.Value & ", Unit: " & strItem
End If
Next subjCell
Else
MsgBox "Item not found: " & strItem & ".pdf"
End If
Next strItem
End With

What is wrong with my order of operations in VBA code?

I have this Excel spreadsheet that I am trying to create a working macro (in VBA) that when a cell containing a date (dates in order by a row in the B column), and this cell is in a specific color, and this cell is active, and the user clicks on a button, the macro searches for all the dates equal to the date in the active cell and to its color. Then in column H, the number value of the respective rows to the found dates are added up and stored into a variable called totalValue Then afterwards, the date, description, and the totalValue are copied over to another sheet and pasted in the next available predefined row.
I know that the color sort works for one color, I am using more than one color layout. The problem is when I run the macro, it seems to add all the number values in Column H within the date and it does not filter out the colors. But, when I take out block of code for "if color equals this, then do math" in lines 52 & 53 (ElseIf rFound.Style.Name = "Shipping" Then totalValue = totalValue + rFound.Offset(0, 6).Value ' THIS VALUE GOES TO Column E "Summary Sheet" ) then the color value for the code above that in lines 49 & 50 works (ElseIf rFound.Style.Name = "Office" Then totalValue = totalValue + rFound.Offset(0, 6).Value ' THIS VALUE GOES TO Column E "Summary Sheet"), but not the code above that lines 46 & 47 unless I take out the code in lines 49 & 50 as well, otherwise it would still add all the values in Column E.
What am I doing wrong? How can I fix it so that it can find the dates in a set color and be able to have several set colors available for use without this addition problem?
The code in question starts at 'BEGINNING OF HELP SEGMENT and ends at 'END OF HELP SEGMENT. The code above, between 'BEGINNING of Search function for HELP SEGMENT and 'ENG of Search function for HELP SEGMENT is the gathering of search parameters.
Here is my code:
Sub Copy_and_Move_Jul()
'
' Copy_and_Move From July Payable Ledger to Jul Summary Macro
'
'BEGINNING of Search function for HELP SEGMENT
'********************************************
'Declare Var
Const AllUsedCellsColumnB = False
Dim rFound As Range, SearchRange As Range
Dim cellValue As Variant, totalValue As Variant
' Get the H value of active row and set it to totalValue
cellValue = Range("H" & ActiveCell.Row)
totalValue = cellValue
' GET & SEARCH FOR COLOR AND DATE OF ACTIVE CELL, AND GET THE VALUES IN COLUMN H AND RETURN VALUE TO "totalValue"
' set search range
Set SearchRange = Range("B7:B56")
' If there is no search range, show Msg
If Intersect(SearchRange, ActiveCell) Is Nothing Then
SearchRange.Select
MsgBox "You must select a cell in the date column before continuing", vbInformation, "Action Cancelled"
Exit Sub
End If
' Get search criteria & set it to rFound
Set rFound = SearchRange.Find(What:=ActiveCell.Value, _
After:=ActiveCell, _
LookIn:=xlValues, _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
SearchFormat:=False)
'********************************************
ENG of Search function for HELP SEGMENT
' BEGINNING OF HELP SEGMENT
'********************************************************************************************************************
' If rFound is not Nothing, then do math. If rFound is Nothing, then findnext
If Not rFound Is Nothing Then
Do
If rFound.Style.Name = "Marketing" Then
totalValue = totalValue + rFound.Offset(0, 6).Value ' THIS VALUE GOES TO Column E "Summary Sheet"
ElseIf rFound.Style.Name = "Inventory" Then
totalValue = totalValue + rFound.Offset(0, 6).Value ' THIS VALUE GOES TO Column E "Summary Sheet"
ElseIf rFound.Style.Name = "Office" Then
totalValue = totalValue + rFound.Offset(0, 6).Value ' THIS VALUE GOES TO Column E "Summary Sheet"
ElseIf rFound.Style.Name = "Shipping" Then
totalValue = totalValue + rFound.Offset(0, 6).Value ' THIS VALUE GOES TO Column E "Summary Sheet"
End If
Set rFound = SearchRange.FindNext(rFound)
' Loop till all matching cells are found
Loop While Not rFound Is Nothing And rFound.Address <> ActiveCell.Address
End If ' End of the Color & Date search
'********************************************************************************************************************
' END OF HELP SEGMENT
'Select & copy Columns B - I of Row of Active Cell
Range("B" & ActiveCell.Row & ":G" & ActiveCell.Row).Select
Selection.Copy
'Go to "Summary" Sheet & Paste data in next available empty Row
Sheets("Summary").Select
Range("B56").End(xlUp).Offset(1, 0).Select
ActiveSheet.Paste
'Select Column D & delete unneeded Qty # and input a "y" for "Expsense"
Range("D" & ActiveCell.Row).Select
Application.CutCopyMode = False
ActiveCell.FormulaR1C1 = "y"
'Set Value of Column H
Range("E" & ActiveCell.Row) = totalValue
'Goto Column C, Check Cell Style and input where supplies came from
Range("C" & ActiveCell.Row).Select
If Worksheets("Summary").Range("C" & ActiveCell.Row).Style.Name = "Marketing" Then
ActiveCell.FormulaR1C1 = "Marketing Supplies"
ElseIf Worksheets("Summary").Range("C" & ActiveCell.Row).Style.Name = "Inventory" Then
ActiveCell.FormulaR1C1 = "Inventory Supplies"
ElseIf Worksheets("Summary").Range("C" & ActiveCell.Row).Style.Name = "Office" Then
ActiveCell.FormulaR1C1 = "Office Supplies"
ElseIf Worksheets("Summary").Range("C" & ActiveCell.Row).Style.Name = "Shipping" Then
ActiveCell.FormulaR1C1 = "Shipping Supplies"
End If
End Sub
Here is a picture, before taking out the code in lines 52 & 53, I hope this helps with my explanation as to what is happening:
Here is a picture, after taking out the code in lines 52 & 53, this is what it's supposed to do:
Much appreciation in advance!
Start by checking if all the style names in the search range have the expected values:
Sub styleNames()
Dim cl As Range, SearchRange As Range
Set SearchRange = Range("B7:B56")
For Each cl In SearchRange
If cl.Value <> vbNullString Then _
Debug.Print " row: " & cl.Row & " style name: " & cl.Style.name
Next cl
End Sub
If they do, then you know for sure it's your code which is the problem. Try rewriting it in a simpler and less convoluted way by introducing conditional statements in the for each loop instead.

Excel VBA macro for one column, if true, apply formula to another column

For context:
I would like for the program to look through column B, identify the first "< / >" (which is purely stylistic and can be changed if necessary - it's only used to break up the data) as the start of a week at cell B9 and the next "< / >" (end of the week) at B16. So the range I'm interested in is B10-B15. It would then sum those numbers from J10 to J15 (Earned column) and paste that sum in L16 (Week Total column). The same could then be done with 'Hours' and 'Week Hours'. For the following week (and thereafter) the 'end of the week' "< / >" becomes the start of the week, and the program continues until B200.
I don't have any experience with VBA and so made the following incomplete attempt (based on what I had found online) but felt too out of my depth not to ask for help.
Sub Work()
Dim rng As Range
Dim rngFound As Range
Set rng = Range("B:B")
Set rngFound = rng.Find("</>")
If rngFound Is "</>" Then
If Cell = "</>" Then
End If
End Sub
Thank you for any help and please let me know if I can be clearer or elaborate on something.
The following code will loop through 200 lines, looking for your symbol. When found, it will sum the numbers in column J for rows between the current row and the last symbol.
I've included two lines that will update the formula. To me, the 2nd one is easier to understand.
Sub Work()
Dim row As Integer
row = 4
Dim topRowToAdd As Integer 'Remember which row is the
'top of the next sum
topRowToAdd = 4
While row <= 200
If Cells(row, 2) = "</>" Then
'Cells(row, 10).FormulaR1C1 = "=SUM(R[" & -(row - topRowToAdd) & "]C[0]:R[" & -1 & "]C[0])"
Cells(row, 10).Value = "=SUM(J" & topRowToAdd & ":J" & row - 1 & ")"
topRowToAdd = row + 1
End If
row = row + 1
Wend
End Sub
Sub Work()
Dim rng As Range, rngFound As Range
Set rng = Range("B:B")
Set rngFound = rng.Find("</>")
If rngFound.Value2 = "</>" Then
'whatever you want to do
End If
End Sub
So at a second glance it looks like this. If you'd like to make it structured you'd need to use a countifs function first.
Sub Work()
Dim rng As Range, rngFound(1) As Range
Set rng = Range("B1:B200")
On Error GoTo Err 'it is quite possible it will run into an error if there are no matches and I'm too lazy for structured solution
Set rngFound(0) = rng.Find(What:="</>", LookAt:=xlWhole, SearchDirection:=xlNext) 'finds the first
Set rngFound(1) = rng.Find(What:="</>", LookAt:=xlWhole, SearchDirection:=xlNext, After:=rngFound(0)) 'finds the first after the first (i.e. the second)
Set rngFound(0) = rngFound(0).Offset(1, 8) '8 is the difference between B and J, row shifts as per description, I advise you to make it a variable
Set rngFound(1) = rngFound(1).Offset(-1, 8)
If rngFound(1).Row > rngFound(0).Row Then 'if it's not higher, then it recurred and found the first range again
rngFound(1).Offset(1, 2).Formula = "=SUM(" & Range(rngFound(0), rngFound(1)).Address & ")" 'L column will have the sum as a formula
Else
MsgBox "There is a single match in " & rng.Address(False, False)
End If
If False Then
Err:
MsgBox "There are no matches in " & rng.Address(False, False)
End If
End Sub
Now for the grand finale:
Sub Work()
Dim rng As Range, rngFound() As Range, rngdiff(1) As Long, rngcount As Long
Set rng = Range("B1:B200")
rngcount = rng.Cells.Count
ReDim rngFound(rngcount)
rngdiff(0) = Range("J1").Column - rng.Column ' the range that needs to be summed is in column J
rngdiff(1) = Range("L1").Column - rng.Column ' the range containing the formula is in column L
On Error GoTo Err 'it is quite possible it will run into an error if there are no matches and I'm too lazy for structured solution
Set rngFound(0) = rng.Find(What:="</>", LookAt:=xlWhole, SearchDirection:=xlNext) 'finds the first
'loop starts
For i = 1 To rngcount
Set rngFound(i) = rng.Find(What:="</>", LookAt:=xlWhole, SearchDirection:=xlNext, After:=rngFound(i - 1)) 'finds the next
If rngFound(i).Row > rngFound(i - 1).Row Then 'if it's not higher, then it recurred and found the first range again
rngFound(i).Offset(0, rngdiff(1)).Formula = "=SUM(" & Range(rngFound(i - 1).Offset(1, rngdiff(0)), rngFound(i).Offset(-1, rngdiff(0))).Address & ")" 'L column will have the sum as a formula
Else
Exit Sub 'if it recurred the deed is done
End If
Next i
If False Then
Err:
MsgBox "There are no matches in " & rng.Address(False, False)
End If
End Sub