VBA Loop through strings - vba

I have to loop through a serious of variables to filter the contents of a dataset to paste it to other sheets. The code I have to paste the data is as follows
Sheets("Source").Select
LastRow = ActiveSheet.Range("A1").Offset(ActiveSheet.Rows.Count - 1, 0).End(xlUp).Row
If ActiveSheet.AutoFilterMode = False Then ActiveSheet.AutoFilterMode = True 'Enable Filters if not exists
ActiveSheet.Range("$A$3:$AY$" & LastRow).AutoFilter Field:=4, Criteria1:= _
"SelectionABC"
Range("A3:AY" & LastRow).Copy
Sheets("DestinationX").Select
Range("A4").Select
ActiveSheet.Paste
The source is always the same, but the "SelectionABC" and the "DestinationX" will change. The selection and detonation are paired, so "SelectionABC" goes to sheet "Destination1", "SelectionDEF" goes to sheet "Destination2",...
How can I loop through the selection & destination so that I don't have the repeat the code for each data transfer?

Here is a quick untested code to help you get going.
Dim i, j As Long
Dim alpha As String
Dim b As Boolean : b = False
j = 1
'~~> UPPERCASE ALPHABETIC CHARACTERS IN THE
'~~> ASCII TABLE GO FROM 65="A" TO 91="Z"
For i = 65 To 91
If i = 89 Then '~~> BECAUSE WE ARE LEFT WITH LAST TWO LETTERS "YZ"
alpha = Chr(i) & Chr(i + 1)
b = True '~~> TO COME OUT OF LOOP AFTER "YZ"
Else
alpha = Chr(i) & Chr(i + 1) & Chr(i + 2)
i = i + 2
End If
Sheets("Source").Select
LastRow = ActiveSheet.Range("A1").Offset(ActiveSheet.Rows.Count - 1, 0).End(xlUp).Row
If ActiveSheet.AutoFilterMode = False Then ActiveSheet.AutoFilterMode = True 'Enable Filters if not exists
ActiveSheet.Range("$A$3:$AY$" & LastRow).AutoFilter Field:=4, Criteria1:= _
"Selection" & alpha '~~> ADDED alpha here
Range("A3:AY" & LastRow).Copy
Sheets("Destination" & j).Select '~~> ADDED j HERE
Range("A4").Select
ActiveSheet.Paste
j = j + 1
If b Then Exit For '~~> TO COME OUT OF LOOP AFTER "YZ"
Next

Related

Excel VBA If Then Else losing date format on first worksheet in Count

I have written some Excel VBA to add weekday dates, down column "A", for 41 worksheets. The dates build to 90 days out and then have a "Beyond mm/dd/yy" text value in the following cell. The code is run every weekday, with the exception of holidays, and builds the dates over the cell that was previously the text cell. This process works beautifully, except for the first of 41 worksheets, where the added date(s) display as text, even though their "format" will say they are a date. The other 40 display as dates. I have attempted to wrap my calculated dates in CDate() and DateValue(), and both. The closes I came was copying down the above cell, but then I will get non-weekdays, as Excel builds the next autofill. I even tried to revisit the one worksheet with the issue and roll through the IF Then Else again, but, with a defined value for the "Beyond" text row and then reassign the dates - this yielded the same result; so, I have concluded that the issue is likely related to how I have written the IF Then Else portion.
Thank you for any ideas~
Dim count As Integer
Sheets("ABCD").Activate
For count = 1 To 41
'*************************************************************************** ********************
'Inserts Dates for weekdays, until 90 days out, then a "Beyond MM/DD/YY" value for the last date
'***********************************************************************************************
Dim ThisSheet As String
'turn off auto formula calculation
Application.Calculation = xlManual
Range("A1").Activate
'find the current "Beyond" date cell
Columns("A:A").Select
Selection.Find(What:="Beyond", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
Range("A" & ActiveCell.Row).Select
'Add business days to column(A:A) until the next business day would be 91 days or greater
Do Until ((Weekday(Range("A" & ActiveCell.Row - 1)) = 6) And _
(DateAdd("w", 3, Range("A" & ActiveCell.Row - 1))) >= (DateAdd("d", 91, Date))) Or _
((Weekday(Range("A" & ActiveCell.Row - 1)) <> 6) And _
(DateAdd("d", 1, Range("A" & ActiveCell.Row - 1))) >= (DateAdd("d", 91, Date)))
If Weekday(Range("A" & ActiveCell.Row - 1)) = 6 Then
ActiveCell.NumberFormat = "m/d/yyyy"
ActiveCell.Value = DateValue(DateAdd("w", 3, Range("A" & (ActiveCell.Row - 1))))
Selection.NumberFormat = "m/d/yyyy"
ElseIf Weekday(Range("A" & ActiveCell.Row - 1)) = 7 Then
ActiveCell.NumberFormat = "m/d/yyyy"
ActiveCell.Value = DateValue(DateAdd("w", 2, Range("A" & (ActiveCell.Row - 1))))
ActiveCell.Select
Selection.NumberFormat = "m/d/yyyy"
Else: ActiveCell.NumberFormat = "m/d/yyyy"
ActiveCell.Value = DateValue(DateAdd("w", 1, Range("A" & (ActiveCell.Row - 1))))
ActiveCell.Select
Selection.NumberFormat = "m/d/yyyy"
End If
Selection.Offset(1, 0).Activate
Loop
'Add in the "Beyond" date, to column(A:A)
ActiveCell.Value = "Beyond " & Format((DateAdd("d", 90, Date)), "mm/dd/yy")
Range("A1").Select
'*****************************************************************************************
'****************************************************************
'Copies down formulas to the last date or "Beyond MM/DD/YYYY" row
'****************************************************************
'Set LastRow Value for end of desired formula range
LTCashSheet_LastRow = Range("A" & Rows.count).End(xlUp).Row
'Set LastRow Value for beginning formulas to copy down
LTCashSheet_BegCopyRange = Range("B" & Rows.count).End(xlUp).Row
Range("B" & LTCashSheet_BegCopyRange & ":N" & LTCashSheet_BegCopyRange).Select
Selection.AutoFill Destination:=Range("B" & LTCashSheet_BegCopyRange & ":N" & LTCashSheet_LastRow), Type:=xlFillDefault
Range("B" & LTCashSheet_BegCopyRange & ":N" & LTCashSheet_LastRow).Select
Columns("A:A").AutoFit
'****************************************************************
'****************************************************************
'Hide Rows 11 through rows prior to today's date row*************
'****************************************************************
Set TheRng = Range("A1", Range("A" & Rows.count).End(xlUp))
CurrDtRow = TheRng.Find(What:=Date, LookAt:=xlWhole).Row
Rows("11:" & (CurrDtRow - 2)).Select
Selection.EntireRow.Hidden = True
Range("A1").Select
'****************************************************************
'Go to next sheet and repeat, through 'count'********************
ActiveSheet.Next.Select
Next count
I found helpful information from Excel VBA date formats. I did not integrate the solution to prevent the above from happening, within my IF THEN ELSE; however, I was able to add some clean up using the function and applying the code to the cells immediately above the "Beyond" value, which were the cells that were a strange hybrid of a String and a Date. I am good to go, but, feel free to comment if you think I should have gone a different route.
Thank you!
Function CellContentCanBeInterpretedAsADate(cell As Range) As Boolean
Dim d As Date
On Error Resume Next
d = CDate(cell.Value)
If Err.Number <> 0 Then
CellContentCanBeInterpretedAsADate = False
Else
CellContentCanBeInterpretedAsADate = True
End If
On Error GoTo 0
End Function
Sub FixDtFrmtWithFnctn()
Dim cell As Range
Dim cvalue As Double
Sheets("NCE1").Select
Set TheRng4 = Range("A1", Range("A" & Rows.count).End(xlUp))
DtFrmtFixRow = TheRng4.Find(What:=("Beyond"), LookAt:=xlPart).Row
Set cell = Range("A" & (DtFrmtFixRow - 1))
If CellContentCanBeInterpretedAsADate(cell) Then
cvalue = CDate(cell.Value)
cell.Value = cvalue
cell.NumberFormat = "m/d/yyyy"
Else
cell.NumberFormat = "General"
End If
Set cell = Range("A" & (DtFrmtFixRow - 2))
If CellContentCanBeInterpretedAsADate(cell) Then
cvalue = CDate(cell.Value)
cell.Value = cvalue
cell.NumberFormat = "m/d/yyyy"
Else
cell.NumberFormat = "General"
End If
Set cell = Range("A" & (DtFrmtFixRow - 3))
If CellContentCanBeInterpretedAsADate(cell) Then
cvalue = CDate(cell.Value)
cell.Value = cvalue
cell.NumberFormat = "m/d/yyyy"
Else
cell.NumberFormat = "General"
End If
End Sub

VBA Selecting cells when it shouldn't with IF Range.Text = "True"?

I have the following code, which is a work in progress, but VBA keeps saying the If Range("G"&CRow).text = "True" then is true in the highlighted row, when it obviously isn't. Can anyone help me figure this out?
Range("G1").FormulaR1C1 = _
"=IF(OR(ISNUMBER(SEARCH(""GS "",RC[-6])),ISNUMBER(SEARCH(""#"",RC[-6]))),""TRUE"",""FALSE"")"
Range("G1").AutoFill Destination:=Range("G1:G" & lastrow)
With Range("G1:G" & lastrow)
.Value = .Value
End With
Dim T As Integer
Dim CRow As Integer
CRow = 1
For Each cell In Range("G1:G" & lastrow)
If Range("G" & CRow).Text = "TRUE" Then
cell.Select
ActiveCell.Offset(0, -5).Select
If Selection.Value = "" Then
Selection.Resize(, 4).Select
Selection.Delete Shift:=xlUp
ActiveCell.Offset(2, 0).Select
Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
CRow = CRow - 1
End If
Else
CRow = CRow + 1
End If
Next
BECAUSE of this
CRow = 1
For Each cell In Range("G1:G" & lastrow)
If Range("G" & CRow).Text = "TRUE" Then
You are assiging 1 to CRow and using that in each iteration. So actually you are always testing Just Row 1.
Change Range("G" & CRow).Text to cell.Text
See below example to delete the same group of cells using a reverse loop and not selecting. I believe I interpreted, and thus changed, this line properly ActiveCell.Offset(2, 0).Select, but let me know if I'm mistaken and it doesn't function as expected.
Range("G1").FormulaR1C1 = _
"=IF(OR(ISNUMBER(SEARCH(""GS "",RC[-6])),ISNUMBER(SEARCH(""#"",RC[-6]))),""TRUE"",""FALSE"")"
Range("G1").AutoFill Destination:=Range("G1:G" & lastrow)
With Range("G1:G" & lastrow)
.Value = .Value
End With
Dim T As Integer
For T = 1 to lastrow Step -1
Set cell = Range("G" & T)
If cell.Text = "TRUE" Then
If cell.offset(0,-5) = "" Then
cell.Offset(0,-5).Resize(,4).Delete Shift=xlUp
Range("G" & T + 2).Insert Shift:=xlDown CopyOrigin:=xlFormatFromLeftOrAbove
End If
End If
Next

Increase number of column and write into selected cell

Good day,
I need help with a little problem. I have a macro which compares cell with range of cells. If the equal cell is not found, it will add the cell at the end of the range. My problem is with equal cell. If it finds it, I need to add 3 to column index and write "X" into this cell.
I have solution for unequal cell but i dont know how to increase column index and write into the cell.
I have this so far:
Sub Compare()
Dim i As Integer
'Comparing cell is from another workbook
Selection.Copy
Windows("zzz.xlsm").Activate
Range("A2").Select
ActiveSheet.Paste
i = 2
Do While Cells(i, 3).Value <> ""
Set FirstRange = Range("C" & i)
If FirstRange.Value = Cells(2, 1).Value Then
MsgBox "Found"
Exit Do
End If
i = i + 1
Loop
If MsgBox = True Then
'Missing code
Else
Range("A2").Select
Selection.Copy
ActiveSheet.Range("E" & Rows.Count).End(xlUp).Offset(1).Select
ActiveSheet.Paste
End If
End Sub
I will appreciate any advice. Thank you for your time.
Sub Compare()
Dim i As Integer
'Comparing cell is from another workbook
Selection.Copy
Windows("zzz.xlsm").Activate
Range("A2").Select
ActiveSheet.Paste
i = 2
Do While Cells(i, 3).Value <> ""
Set FirstRange = Range("C" & i)
If FirstRange.Value = Cells(2, 1).Value Then
MsgBox "Found"
Exit Do
End If
i = i + 1
Loop
If MsgBox = True Then
Cells(i, 6) = "X" 'used to be Missing code
Else
Range("A2").Select
Selection.Copy
ActiveSheet.Range("E" & Rows.Count).End(xlUp).Offset(1).Select
ActiveSheet.Paste
End If
End Sub

How to only copy values using VBA

I need to copy values only without Formula from sheet to another. The following code does copy but only with Formula. I tried some solutions presented in this site but they give me errors.
For i = 2 To LastRow
'sheet to copy from
With Worksheets("Hoist")
'check column H value before copying
If .Cells(i, 8).Value >= -90 _
And CStr(.Cells(i, 9).Value) <> "Approved" _
And CStr(.Cells(i, 9).Value) <> "" _
And CStr(.Cells(i, 10).Value) = "" Then
'copy row to "display" sheet
.Rows(i).Copy Destination:=Worksheets("display").Range("A" & j)
j = j + 1
End If
End With
Next i
Try changing this line:
.Rows(i).Copy Destination:=Worksheets("display").Range("A" & j)
to this:
.Rows(i).Copy
Worksheets("display").Range("A" & j).PasteSpecial xlPasteValues
This however drops all formatting. To include formatting, you'll need to add another line like:
Worksheets("display").Range("A" & j).PasteSpecial xlPasteFormats
Another option is to enter a working column and use AutoFilter to avoid loops
insert a column in column A
the working column formuka is =AND(I2>-90,AND(J2<>"",J2<>"Approved"),K2="")
filter and copy the TRUE rows
delete working column A
code
Sub Recut()
Dim ws As Worksheet
Dim rng1 As Range
Set ws = Sheets("Hoist")
ws.AutoFilterMode = False
Set rng1 = Range([h2], Cells(Rows.Count, "H").End(xlUp))
ws.Columns(1).Columns.Insert
rng1.Offset(0, -8).FormulaR1C1 = "=AND(RC[8]>-90,AND(RC[9]<>"""",RC[9]<>""Approved""),RC[10]="""")"
With rng1.Offset(-1, -8).Resize(rng1.Rows.Count + 1, 1).EntireRow
.AutoFilter Field:=1, Criteria1:="TRUE"
.Copy Sheets("display").Range("A1")
Sheets("display").Columns("A").Delete
End With
ws.Columns(1).Delete
ws.AutoFilterMode = False
End Sub

Malformed VLookup formula when trying to use Range.Formula property

I have Excel sheets that will have data from many sources that will be grouped together so that what needs to be looked upon is above what you are looking from so there will be many VLookups on separate portions of one sheet.
Sub linkFDCfdv()
Range("A1").Select
Dim doesFDChaveDescription As Boolean
Dim isLastRowFDC As Boolean
Dim myRange As String
Dim firstFDCrow As Long
Dim lastFDCrow As Long
While Len(Selection.Value) > 0
If Selection.Value = "FDC" Then
If isLastRowFDC = False Then
firstFDCrow = ActiveCell.Row
End If
isLastRowFDC = True
ActiveCell.Offset(0, 3).range("A1").Select
If Len(Selection.Value) > 0 Then
doesFDChaveDescription = True
Else
doesFDChaveDescription = False
End If
ActiveCell.Offset(0, -3).range("A1").Select
Else
If isLastRowFDC = True Then
lastFDCrow = ActiveCell.Row - 1
End If
End If
If Selection.Value = "FDV" Then
ActiveCell.Offset(0, 10).range("A1").Select
myRange = "B" & firstFDCrow & ":D" & lastFDCrow
ActiveCell.Formula = "=VLOOKUP(R[0]C[-2]," & myRange & ",2)"
ActiveCell.Offset(0, -10).range("A1").Select
End If
ActiveCell.Offset(1, 0).range("A1").Select
Wend
End Sub
What's happening is that my macro makes the formula:
=VLOOKUP(I9,'B3':'D8',2)
If I take out the ' marks the macro works perfectly.
That is because you are using a mix of R1C1 style with A1 style. Is this what you are trying?
ActiveCell.Formula = "=VLOOKUP(" & ActiveCell.Offset(,-2).Address & _
"," & myRange & ",2)"