Sub SeperateRowSub()
Dim FirstRowPFW As Integer
Dim LastRowPFW As Integer
FirstRowPFW = Range("B:B").Find(what:="Planning/Fieldwork", after:=Range("B6")).Row
LastRowPFW = Range("B:B").Find(what:="Planning/Fieldwork", after:=Range("B6"), searchdirection:=xlPrevious).Row
End Sub
FirstRowPFW returns the correct row that it starts at.
Lastrow continues to count the rest of the rows, even those outside of the "planning/fieldwork" criteria.
How can I fix the lastrowpfw variable to only count to the last row for cells containing "Planning/Fieldwork" ?
You code appears to function with correct data:
Sub SeperateRowSub()
Dim FirstRowPFW As Integer
Dim LastRowPFW As Integer
FirstRowPFW = Range("B:B").Find(what:="Planning/Fieldwork", after:=Range("B6")).Row
LastRowPFW = Range("B:B").Find(what:="Planning/Fieldwork", after:=Range("B6"), searchdirection:=xlPrevious).Row
MsgBox FirstRowPFW & vbCrLf & LastRowPFW
End Sub
I found that the problem was it was referencing a formula for Planning/Fieldwork, i.e. that text came up conditionally. When I put a hardcoding statement in for that reference, it works. Thank you for your help anyway!
Related
I have a problem:
Public Sub ChangeRow(Column As String, Value As String, id As Integer)
For i = 4 To 15
For Each rw In Worksheets(i).Rows
If Worksheets(i).Range("A" & rw.row).Value = id Then
Dim row As Integer
**row = getRow(id, i)**
MsgBox (row)
If Worksheets(i).Range(Column & rw.row).Value <> Value Then
Worksheets(i).Range(Column & rw.row) = Value
End If
Exit For
End If
Next rw
Next i
End Sub
Function getRow(id As Integer, Sheet As Integer) As Integer
For Each rw In Worksheets(Sheet).Rows
If Worksheets(Sheet).Range("A" & rw.row).Value = id Then
getRow = rw.row
End If
Next rw
End Function
Change Row Works fine... its just when I add 'row = getRow(id, i)' to the mix it throws a ByRef mismatch error??
This is a great example as to why using Option Explicit is a great practice.
Add Option Explicit to the very top of your worksheet module, outside your macro.
This forces you to declare all variables used in your subs, and also can help catch typos in your variable names.
This would catch that i is not declared. What's therefore happening is VBA/Excel by default will set i to be Variant.
Then, when you hit row = getRow(id, i), you're basically passing row = getRow([integer], [Variant]). But that sub is expecting getRow([integer],[integer])...hence your Type Mismatch error.
So, as mentioned, just do Dim i as Integer at the top of the ChangeRow sub.
(or, for long run VBA use Long instead of Integer).
In the function, you need to declare "Sheet" as Worksheet object
Function getRow(id As Integer, Sheet As Worksheet) As Integer
I am trying to find specific values in a worksheet and pull other info from there. However, sometimes that value occurs multiple times. In those cases I want to sum another set of values that'll be found in the same row as the found value. The code below works well to identify a specific instance of a value and then pull info ( that is the "do stuff" portion), but how would I go about looping it to pull all instances of the value and store their addresses temporarily?
Thanks!
Dim AccountsListLength As Integer
Dim AccountsLength As Integer
Dim CurrentAccount As String
Dim SearchISIN As String
Dim CurrentAccountPage As Range
Dim FoundISIN As Range
Dim i As Integer
SearchISIN = Worksheets("Search").Range("SearchISIN").Value
AccountsListLength = (Worksheets("DataSheet").Range("AccountList").Count)
AccountsLength = AccountsListLength - 1
For i = 0 To AccountsLength - 1
CurrentAccount = Worksheets("DataSheet").Range("AccountList")(i + 2)
Set CurrentAccountPage = Worksheets(CurrentAccount).UsedRange
Set FoundISIN = CurrentAccountPage.Find(what:=SearchISIN, LookIn:=xlValues, _
LookAt:=xlPart, MatchCase:=False)
If Not FoundISIN Is Nothing Then
'Do stuff
End If
You could also use FindNext.
You need to have one more var to make sure your findNext-method doesnt start all over when it reaches the last occurence
Dim nextISIN As Range
For i = 0 To AccountsLength - 1
CurrentAccount = Worksheets("DataSheet").Range("AccountList")(i + 2)
Set CurrentAccountPage = Worksheets(CurrentAccount).UsedRange
Set FoundISIN = CurrentAccountPage.Find(what:=SearchISIN, LookIn:=xlValues, _
LookAt:=xlPart, MatchCase:=False)
Set nextISIN = CurrentAccountPage.FindNext(FoundISIN)
If Not FoundISIN Is Nothing Then
Do Until FoundISIN == nextISIN
'Do stuff
Set nextISIN = CurrentAccountPage.FindNext(nextISIN)
Loop
End If
This should work. However, Im writing from my cellphone while riding the train so there might be some syntax-error.
I hope it helps :)
Edit: just wanted to post my comment here for a more clear view on the code
If you have a range already then you could loop through it and see if your SearchISIN appears more than once. If it doesn't, then do stuff to it.
Dim tempCell As Range
Dim Occurrences As Int
For Each tempCell In givenRange
If tempCell.Value == SearchISIN Then
Occurrences = Occurrences + 1
End If
Next tempCell
If Occurrences == 1 Then
'Find the cell and do stuff to it
End If
I'm not 100% sure on what you want to do though. Try posting some data structure next time and it will be easier for people to help :)
Private Sub FillRow(programCell As Range, storedProgramCell As Range)
Dim counter As Integer
For counter = 3 To 9
Dim cellOffset As Integer
cellOffset = counter - 3
Dim currentStoredCell As Range
Set currentStoredCell = storedProgramCell.Offset(0, cellOffset)
Dim value As String
value = currentStoredCell.value
Dim currentTargetCell As Range
Set currentTargetCell = programCell.Offset(0, cellOffset)
MsgBox currentStoredCell.value 'Works correctly, prints correct value
currentTargetCell.value = value
Next counter
End Sub
The line:
currentTargetCell.value = value
causes the code to stop executing, with no error.
I added the expression to my watch list, then stepped through the routine. The expression was seen as a Boolean:
This makes me think the expression is being viewed as a comparison, and the program abruptly ends since the returned Boolean is not being stored or used anywhere. I wouldn't doubt if I were wrong though.
I'm new to VBA, struggling to debug my program, so please forgive me if this is a petty mistake. I couldn't find any sources online that explains this problem.
Replace your subroutine with following code:
Private Sub FillRow(Dst As Range, Src As Range)
Dim x As Integer
Dim v As Variant
Dim Srcx As Range
Dim Dstx As Range
Debug.Print "FillRow"
Debug.Print Src.Address
Debug.Print Dst.Address
Debug.Print "Loop"
For x = 0 To 6
Debug.Print x
Set Srcx = Src.Offset(0, x)
Debug.Print Srcx.Address
v = Srcx.Value
Debug.Print TypeName(v)
Set Dstx = Dst.Offset(0, x)
Debug.Print Dstx.Address
Dstx.Value = v
Next
Debug.Print "Completed"
End Sub
Run and post in your question Immediate window output.
Value is a reserved word, even if vba does not raise an error on this name, you should not use it. Name it something else. Also, try setting it as a variant.
My excel sheet is filled with zeroes except for one cell in every row.
I want to find that cell and return the column.
For example: In the cell T616 is a value other than 0. May it be -15400.
I want to find that cell(T616) based on the row(616) and have the column returned(T). May it even be in a MsgBox.
This is my result of many tries and long Google-sessions:
Public Function find_Column(lRange As Range, lValue As String) As Integer
Dim vCell As Range
For Each vCell In lRange.Cells
If vCell.Value = lValue Then
find_Column = vCell.Column
MsgBox (find_Column)
Exit Function
End If
Next vCell
End Function
I found this code somewhere and modified it a little bit, but I can't remember where. So thanks to the creator!
How do I search for a number other than 0?
I'm relatively new to VBA and don't really have an idea what I am doing. Sorry for my bad English (foreigner). I'd appreciate any help. Thank you!
Try this:
Public Function findNonZeroValueInColumn(lRange As Range) As Integer
Dim vCell As Range
For Each vCell In lRange.Cells
If vCell.Value <> 0 Then
find_Column = vCell.Column
Exit Function
End If
Next vCell
End Function
Sub ShowValue()
call MsgBox(findNonZeroValueInColumn(Range("A:A")))
End Sub
Remember that Functions are supposed to return values. Subs (Procedures) do not return values.
The <> symbol is the "Not Equal" Comparison. So if you wanted to check if a cell didn't equal 0, you would write
If vCell.Value <> 0 Then
... ' rest of code here
In your problem:
Public Function find_Column(lRange As Range) As Integer
Dim vCell As Range
For Each vCell In lRange.Cells
If vCell.Value <> 0 Then
find_Column = vCell.Column
MsgBox (find_Column)
Exit Function
End If
Next vCell
End Function
Also since you are only checking against 0, you wouldn't need the extra lValue As String argument.
As the other part of your question has been answered while I was typing, if you want to return the column letter instead of the number...
find_Column = Replace(Replace(vCell.Address, vCell.Row, ""), "$", "")
If this is what you want the function to return, you would have to change the type your function is returning to string
I would like to create a macro in excel that lets me increment the counts of a part whenever I press a command button.
Currently, my concept is to use vlookup to get the existing counts for that part using the following. However, it does not increment the actual counts value in the cell, which is what I want. I suspect it's cos vlookup is only used to return a value within the cell, but the cell is not activated in the process for actual increment. Can someone please advise how I can correct it? I'm still new to vba. Thanks!!! :)
E.g. Vlookup finds C1value in Cell A5 of Sheets("Location"). It will automatically increment the value in Cell C5 by 1.
Sub FindAddTools()
Dim C1Qnty As Double
C1value = Sheets("Issue").Range("D11")
Sheets("Location").Activate
C1Qnty = WorksheetFunction.VLookup(C1value, Range("A:D"), 3, False)
C1Qnty = C1Qnty + 1
End Sub
ADD ON: an add-on to my original question. I was wondering if it is possible to do the same for an entire range?
E.g. C1value is now a range of Sheets("Issue").Range("D11:D20"). I want to find all values within this range in Sheets("Location") and increment their corresponding counts in Column C.
Is there a way to do this without repeating the same procedure for all cells of the range?
Thanks! :)
Here's my shot at it. If the value isn't matched nothing happens:
Sub FindAddTools()
Dim RangeToMatch As Excel.Range
Dim cell As Excel.Range
Dim C1Value As Variant
Dim C1Row As Variant
Set RangeToMatch = Sheets("Issue").Range("D2:D11")
For Each cell In RangeToMatch
C1Value = cell.Value
With Sheets("Location")
C1Row = Application.Match(C1Value, .Range("A:A"), 0)
If Not IsError(C1Row) Then
.Range("C" & C1Row).Value = .Range("C" & C1Row).Value + 1
End If
End With
Next cell
End Sub
I edited it so that it cycles through a range of cells to match. That range is set to D2:D11 above.
Based on your comments, I think this should do it.
NB: you don't have to Activate worksheets to perform the functions referencing their cells/ranges.
Sub FindAddTools()
Dim shIssue as WOrksheet: Set shIssue = Sheets("Issue")
Dim shLoc as Worksheet: Set shLoc = Sheets("Location")
Dim allC1Values as Range
Dim C1Value as Variant
Dim C1Qnty As Double
Dim foundRow as Long
Set allC1Values = shIssue.Range("D11:D100") '## Modify as needed.
For each C1Value in allC1Values.Cells
C1Qnty = WorksheetFunction.VLookup(C1value, shLoc.Range("A:D"), 3, False)
C1Qnty = C1Qnty + 1
foundRow = WorksheetFunction.Match(c1Value,shLoc.Range("A:A"),False)
shLoc.Range("C" & foundRow).Value = CqQnty
Next
End Sub
Be careful with this. You're immediately writing to the same cell you just "found" with the VLOOKUP function, so, obviously if you run this macro again, you're going to increment it again. But, this may be the desired functionality, if so, no problem.
NOTE: There is no error trapping for if C1Value is not found in the VLOOKUP or MATCH functions.