Usng variables as column names within a range - excel

can i have some assistance with the syntax to refer to a an entire row (or column) within a range ?
I know that i can specify a row (row 1) to perform some functions like this:
With ws1.Range("1:1")
....
End With
How do i specify a row using a variable ? For example
With ws1.Range("rowVariable:rowVariable")
...
End With
Test Data:
freqPlan freqChan freq2Update fNote
Narrow81 AB31' 90.111110 N67
Narrow81 B842 99.880000 N68
Narrow81 B842' 99.880000 N68
My Code:
Sub remFootnote()
Dim ws1 As Worksheet
Set ws1 = Sheet1
Dim lastRow, Index, i As Integer
Dim freq2Update, freqPlan, freqChan, fNote As String
freq2Update = 99.88
freqPlan = "Narrow82"
freqChan = "B842'"
fNote = "N68"
lastRow = ws1.Range("A1").End(xlDown).Row
For Index = 2 To lastRow
i = Index
If ws1.Range("A" & i).Value = "Narrow81" Then
If ws1.Range("B" & i).Value = "B842'" Then
With ws1.Range("i : i") '**this is the line i have issues with**
Set d = .Find(fNote, LookIn:=xlValues) 'when fnote is found in Row "i"
d.ClearContents 'delete it
End With
End If
End If
Next Index
End Sub
I have the watch window activated to see my variables and the code above works fine up to the line where i try to execute this line:
With ws1.Range("i : i")
I have tried the following variations to no avail:
With ws1.Range("i : i")
With ws1.Range(i:i)
With ws1.Range(i":"i)
Any assistance would be greatly appreciated.

A few issues here:
Just use Range.EntireRow
Not sure why you need variables Index and i - since they are the exact same thing, just use one
You need to add Dim d as Range to your code. Also, you have to assign variable types each time. The comma seperated method you are using is not correct
You need to code for the chance that your value is not found in the row you are searching. So, check to make sure your range variable d is not Nothing before taking any action
The better way to find the last row is to go from bottom up (ws1.Range("A" & ws1.Rows.Count).End(xlUp).Row)
Putting all this together:
'Poper way to declare variables
Dim lastRow as Long, i As Long
Dim freqPlan as String, freqChan as String, fNote As String
Dim freq2Update as Double
Dim d as Range
'Assign variable values here
ws1.Range("A" & ws1.Rows.Count).End(xlUp).Row
'Simplified loop
For i = 2 To lastrow
If ws1.Range("A" & i) = "Narrow81" And ws1.Range("B" & i) = "B842" Then
Set d = ws.Range("A" & i).EntireRow.Find(fNote, LookIn:=xlValues)
If Not d Is Nothing Then d.ClearContents
Set d = Nothing
End If
End If

Try replacing of
With ws1.Range("i : i") '**this is the line i have issues with**
Set d = .Find(fNote, LookIn:=xlValues) 'when fnote is found in Row "i"
d.ClearContents 'delete it
End With
with
With ws1.Range(i & ":" & i) 'the string range must be built from the variable concatenated with ":"...
Set d = .Find(fNote, LookIn:=xlValues)
d.ClearContents 'clears its contents
End With
or even simpler, with:
With ws1.Rows(i)
Set d = .Find(fNote, LookIn:=xlValues)
d.ClearContents 'clears its contents
End With

Related

Copy/Paste Date using VBA

I am trying to insert the date using the Today Function in Excel. I have a sheet with the date at the top, in Cell I2.
I have a table and am using VBA to copy paste values into it - this will be used daily and I want the date to be auto populated into Column D, starting from the last used row in Column D and ending with the last used row in Column C. I then want the date to be saved as value.
I tried using the following code but it didn't work - nothing happened.
Can someone please help me understand why, and how to correct this?
With ThisWorkbook
With .Sheets("Test")
Dim rng As Range
Set rng = .Range(.Cells(.Rows.Count, "D").End(xlUp), .Cells(.Rows.Count, "C").End(xlUp).Offset(0, 1))
rng.Value = ThisWorkbook.Sheets("Test").Range("I2").Value
End With
End With
I believe this is what you want:
Find the last used row with Column C (Assumes the last row in C & D are equal so just calculate this in one column. It looks like you are trying to over-complicate)
Skip the temp rng assignment and apply the value transfer using a combination of Offset when calculating lr and Resize when referencing the target row
Sub Try_Me()
Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Test")
Dim lr As Long
lr = ws.Range("C" & ws.Rows.Count).End(xlUp).Offset(1).Row
ws.Range("C" & lr).Resize(1, 2).Value = ws.Range("I2").Value
End Sub
Looking at your current Set rng = ... statement it looks like you may be trying to determine the last used row in either column indicating that the last used row in both may vary. If that is the case, you can compare both and pick the max like so:
Sub Try_Me()
Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet2")
Dim c As Long, d As Long, lr As Long
c = ws.Range("C" & ws.Rows.Count).End(xlUp).Offset(1).Row
d = ws.Range("C" & ws.Rows.Count).End(xlUp).Offset(1).Row
lr = Application.WorksheetFunction.Max(c, d)
ws.Range("C" & lr).Resize(1, 2).Value = ws.Range("I2").Value
End Sub

Search whole sheet with find returns empty values

I am trying to search a whole sheet with the below code. Essentially workbook A has a column of values (codes) in (column A) and searches that code in workbook B. Workbook B has codes with their descriptions, those descriptions are to the right of the code, but the distance is variable (which is why it's xlToRight, rather than offset).
It works when I put a breakpoint and run the code manually, however, running the code turns up empty searches. I have tried setting the search value as
FindString = MainSht.Range("A" & x).Value
as well as
FindString = MainSht.Range("A" & x).Text
but both turn up empty searches (or rather they return an "N/a" which is wrong cause I find the values when searching manually).
I need to be able to search the whole worksheet so I am setting the range as .Cells.
Sub One_Find()
Dim Compld As Range
Dim FindString As String
Dim x, NumRows As Integer
Dim MainSht, SearchSht As Worksheet
Dim MainBk, SearchBk As Workbook
Set MainBk = ThisWorkbook
Set SearchBk = ActiveWorkbook
Set MainSht = MainBk.Sheets("Curr des")
Set SearchSht = SearchBk.Sheets("Current")
Set SearchRng = SearchSht.UsedRange '.Cells
NumRows = MainSht.Cells(MainSht.Rows.Count, "A").End(xlUp).Row
For x = 2 To NumRows
FindString = MainSht.Range("A" & x).Text
With SearchRng
Set Compld = .Find(what:=FindString, LookIn:=xlValues, lookat:=xlWhole)
If Not Compld Is Nothing Then
MainSht.Range("B" & x).Value = Compld.End(xlToRight).Value
Else
MainSht.Range("B" & x).Value = "N/a"
End If
End With
Next
End Sub
Let me know if you need more information!

Finding if a cell values (delimited by comma) are all existing in a defined table

Here is a sample of the report I have:
Basically the report consists in a huge list of suppliers where among other things, I need to identify which of them have all entities (content groups) for the same country, while ignoring the "integrate" tag. Entities for each country are defined in a table separately (right).
So far I tried a combination of =SUMPRODUCT(--(ISNUMBER(SEARCH())) but always getting partially what I want.
In column C, in need:
to display YES if the supplier on that row has all entities for the mentioned country code;
to display NO otherwise;
My logic on this:
The formula/s needs to pick the country code from 1st table, then look into the 2nd table where entities are defined and check if all the entities in the content group are matching, ignoring "integrate" which is a default tag applied everywhere.
Expected result:
Try:
Option Explicit
Sub test()
Dim ws1 As Worksheet, ws2 As Worksheet
Dim LastRowA As Long, i As Long, y As Long
Dim arr As Variant
Dim CountryCode As String
Dim rng As Range, SearchRange As Range, FindPosition As Range
Dim Appears As Boolean
'Set worksheets on variables
With ThisWorkbook
Set ws1 = .Worksheets("Sheet1")
Set ws2 = .Worksheets("Sheet2")
End With
'Set the range to search in for country codes
Set SearchRange = ws2.Range("H1:R1")
With ws1
'Find the last row of Column A sheet1
LastRowA = .Cells(.Rows.Count, "A").End(xlUp).Row
'Start loop from row 2 to last row sheet1
For i = 2 To LastRowA
'Criteria needed ( Column A - Not empty cell, Column D - Includes "Europe" & Column E - Includes "No" Columns D and E are CASE SENSITIVE)
If .Range("A" & i).Value <> "" And .Range("D" & i).Value = "Europe" And .Range("E" & i).Value = "No" Then
CountryCode = .Range("B" & i).Value
'In which column the country code found
Set FindPosition = SearchRange.Find(What:=CountryCode, LookIn:=xlValues, LookAt:=xlWhole)
'If code excist
If Not FindPosition Is Nothing Then
'Set the range to search for the groups in the column where the code is header
Set rng = ws2.Range(ws2.Cells(2, FindPosition.Column), ws2.Cells(ws2.Cells(ws2.Rows.Count, FindPosition.Column).End(xlUp).Row, FindPosition.Column))
'Split the string with comma and assing it on arr
arr = Split(.Range("A" & i).Value)
Appears = False
'Loop the arr
For y = LBound(arr) To UBound(arr)
'Check if the arr(y) start from C as all code start from C
If Left(arr(y), 1) = "C" Then
'Count how many times the arr(y) with out the comma appears in the rng
If Application.WorksheetFunction.CountIf(rng, Replace(arr(y), ",", "")) > 0 Then
'If appears the variable Appears is true
Appears = True
Else
'If does not appear the variable Appears is False & Exit the loop
Appears = False
Exit For
End If
End If
Next y
'Check Appears variable status and import value in Column C
If Appears = True Then
.Range("C" & i).Value = "Yes"
Else
.Range("C" & i).Value = "No"
End If
'If code does not excist
Else: MsgBox "Country Code not does not excist."
End If
End If
Next i
End With
End Sub
If you have a version of Excel 2013+ which has the FILTERXML function, you can use this array formula:
=IF(OR(ISNA(MATCH(FILTERXML("<t><s>"&SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(A2,"Integrate",""),", ",","),",","</s><s>")&"</s></t>","//s"),INDIRECT("Table2["&B2&"]"),0))),"No","Yes")
We remove the Integrate
Create an XMLfrom the strings in Table1
Extract each element of the XML
Try to find them in the appropriate column of Table2
If we don't find one, then it has multiple countries.
Since this is an array formula, you need to "confirm" it by holding down ctrl + shift while hitting enter. If you do this correctly, Excel will place braces {...} around the formula as observed in the formula bar
If you have a version of Excel that does not have this function, and you are still interested in using excel formulas as opposed to VBA, there is another formula we can use.

Assigning a row range to a variable

I have been trying so hard. I cant figure this out. I am working with two sheets. One sheet searches for a criteria "RR", ir there is an RR, it assigns a variable a serial to be searched in another sheet. If the serial is found in the other sheet, I would like to determine the row where it is located and assign it to a variable. "DidTransfer = Sheets(PreviousTabName).Range("B" & thiscell.Row).Value" The problem when I use thiscell.Row, its giving me so many problems. I need the row number to so I can reference the same row to get information from another cell on the same row. Please help.
Sub TempModifier()
Dim NYSID, PLookUpTabRange, IsRR, DidTransfer As String
Dim thiscell As Range
'Variable for Temp
Dim TempFirstRow As Integer
Dim TempLastRow As Long
'Variables for the previous
Dim PreviousTabLastRow As Long
Dim PreviousTabFirstRow As Integer
'Initialize the temp variables
TempLastRow = Sheets("Temp").Range("D" & Rows.Count).End(xlUp).Row
PreviousTabName = "February"
PreviousTabFirstRow = 7
With Sheets(PreviousTabName)
PreviousTabLastRow = .Cells(256, "H").End(xlUp).Row 'Get the last row in the data range
End With
'Create a data-range variable
PLookUpTabRange = "H" & PreviousTabFirstRow & ":" & "H" & PreviousTabLastRow
'Begin looping structure to copy data from the temp tab to the current tab
For TempFirstRow = 2 To TempLastRow
'Assign the value of the housing unit
IsRR = Sheets("Temp").Cells(TempFirstRow, 2).Value
'Check if the value is RR
If IsRR = "RR " Then
'If the value is RR, then get the NYSID
NYSID = Worksheets("Temp").Cells(TempFirstRow, 4).Value
If Not IsError(Application.Match(NYSID, Worksheets(PreviousTabName).Range(PLookUpTabRange), 0)) Then
'NYSID is Found on Current Month Sheet, do Nothing
Else
DidTransfer = ""
Set thiscell = Sheets(PreviousTabName).Columns("D").Find(What:=NYSID, LookIn:=xlValues, lookat:=xlWhole)
DidTransfer = Sheets(PreviousTabName).Range("B" & thiscell.Row).Value
Select Case DidTransfer
Case "Transferred"
DidTransfer = "Transferred"
Case Else
DidTransfer = DidTransfer
End Select
If IsError(Application.Match(NYSID, Worksheets(PreviousTabName).Range(PLookUpTabRange), 0)) Or _
(Not IsError(Application.Match(NYSID, Worksheets(PreviousTabName).Range(PLookUpTabRange), 0)) And _
DidTransfer = "Transferred") Then
'Worksheets("Temp").Rows(TempFirstRow).Delete
MsgBox "Delete"
End If
End If
End If
'Go to the next row
Next TempFirstRow
End Sub

If 0 clear contents for multiple columns

I'm wondering how to make the following code work for multiple columns (D:P)? I've already tried adding & ":"P" & "65536" to the range, without success.
For i = 5 To Range("D" & "65536").End(xlUp).Row Step 1
If Application.WorksheetFunction.CountIf(Range("D" & i), "0") = 1 Then
Range("D" & i).ClearContents
End If
Next i
You can use Range("D5:P65536").Replace What:=0,Replacement:="" to Replace all at once.
Loop through the actual column and use the Find() method to perform your search. If your value exists in that range (range = column), then you can clear the contents that way.
Sub test()
' Just for illustration on the columns
Const D& = 4: Const P& = 16
Dim ws As Worksheet, col As Long
Set ws = ThisWorkbook.Worksheets(1)
For col = D To P
If Not ws.Columns(col).find(What:="0", LookAt:=xlWhole) Is Nothing Then
ws.Columns(col).ClearContents
End If
Next col
End Sub

Resources