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

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

Related

Excel VBA to SUMIF Range only if Range is not completely Blank

I have a data issue that has been perplexing me for a few weeks now.
Goal:
- Sum set range into new reference cell. Perform this for 8 different ranges spanning 42 columns. This needs to be performed on a row by row basis so each entry has their appropriate numbers.
- Columns L:S should only have a value if the SUM range itself had any values. No false 0's.
Issues:
- The SUM Function works, but it is returning a 0 in situations when there were no values to Sum. This is an issue as 0 is a valid value, and the extra 0's throw off averages of those who actually have values.
- SUMIFS is returning TRUE instead of a value (I use SUMIFS with 1 criteria as it is easier for me to understand, don't focus on that bit as it did the same thing when I had it in the SUMIF formula).
Here is my VBA in it's entirety:
Sub BE_Candidate_Flow_Time()
'
' BE_Candidate_Flow_Time Macro
'
Dim StartCell As Range
Dim RangeName As String
Dim myValue As Variant
Set StartCell = Range("A1")
myValue = InputBox("Enter Date: YY-MMM")
StartCell.CurrentRegion.Select
RangeName = "Dataset"
Dim LRow As Long
Dim lCol As Long
LRow = Cells(Rows.Count, 1).End(xlUp).Row
lCol = Cells(1, Columns.Count).End(xlToLeft).Column
Columns("J:Q").Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
Columns("A:B").Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
Range("A1").FormulaR1C1 = "Application ID"
Range("B1").FormulaR1C1 = "Timeframe"
Range("K1").FormulaR1C1 = "Job Code"
Range("L1").FormulaR1C1 = "Time to Complete the Assessment"
Range("M1").FormulaR1C1 = "Applied/Assessed and Ready for Review"
Range("N1").FormulaR1C1 = "Time being Reviewed and Interviewed"
Range("O1").FormulaR1C1 = "Time to Accept the Offer"
Range("P1").FormulaR1C1 = "Consent to Pre-Hire Screenings"
Range("Q1").FormulaR1C1 = "Run the Pre-Hire Screenings"
Range("R1").FormulaR1C1 = "Waiting to be sent to Onboard"
Range("S1").FormulaR1C1 = "In Onboard"
Range("A2", "A" & LRow).FormulaR1C1 = "=CONCATENATE(RC[2],RC[5])"
Range("B2", "B" & LRow).Value = myValue
Columns("T:BI").NumberFormat = "0.00"
Range("L2", "L" & LRow).FormulaR1C1 = "=SUMIFS({RC[9];RC[13]},{RC[9];RC[13]}," <> ")"
Range("M2", "M" & LRow).FormulaR1C1 = "=SUMIFS({RC[7];RC[9]:RC[11];RC[13]:RC[16]},{RC[7];RC[9]:RC[11];RC[13]:RC[16]}," <> ")"
Range("N2", "N" & LRow).FormulaR1C1 = "=SUMIFS({RC[16]:RC[27]},{RC[16]:RC[27]}," <> ")"
Range("O2", "O" & LRow).FormulaR1C1 = "=SUMIFS({RC[27]:RC[31];RC[33]:RC[34]},{RC[27]:RC[31];RC[33]:RC[34]}," <> ")"
Range("P2", "P" & LRow).FormulaR1C1 = "=SUMIFS({RC[34]},{RC[34]}," <> ")"
Range("Q2", "Q" & LRow).FormulaR1C1 = "=SUMIFS({RC[35]:RC[40]},{RC[35]:RC[40]}," <> ")"
Range("R2", "R" & LRow).FormulaR1C1 = "=SUMIFS({RC[40]:RC[41]},{RC[40]:RC[41]}," <> ")"
Range("S2", "S" & LRow).FormulaR1C1 = "=SUMIFS({RC[41]:RC[42]},{RC[41]:RC[42]}," <> ")"
Range("K1", "K" & LRow).AutoFilter 1, ""
Range("K2", "K" & LRow).FormulaR1C1 = "=RC[-1]"
[K1].AutoFilter
Cells.Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
Range("J:J,T:BI").Delete Shift:=xlToLeft
Range("A1").Select
End Sub
You could add a if to the formula directly.
Somthing like
=IF(
count({RC[7];RC[9]:RC[11];RC[13]:RC[16]})>0;
SUM({RC[7];RC[9]:RC[11];RC[13]:RC[16]};
""
)

VBA Loop through strings

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

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

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

comparing a single value against an array in VBA

Sub CHECKas()
Dim lastrow As Long
Dim lastcol As Long
Dim l As Integer
Dim i As Integer
Dim rname As Constants
Set rngTarg = Selection
lastrow = Sheets("report").Range("B" & Rows.Count).End(xlUp).row
lastcol = Sheets("report").Cells(2, Columns.Count).End(xlToLeft).Column
Sheets("FEBBRAIO").Select
ActiveCell.Offset(0, -3).Copy
Sheets("REPORT").Select
Cells(1, lastcol + 1).PasteSpecial xlPasteAll
Application.CutCopyMode = False
rname = Application.ActiveCell.Value
ActiveCell.Offset(1, 0).Select
For i = 2 To lastrow
ThisWorkbook.Sheets("report").Select
If Range("f2:f" & lastrow) <= Val(CStr(rname.Value)) _
And Range("g2:g" & lastrow) > Val(CStr(rname.Value)) Then
Cells(i, ActiveCell.Column).Value = "1"
Else
Cells(i, ActiveCell.Column).Value = 0
End If
Next i
End Sub
I'm new in VBA and I can't understand how to compare a constant value with each cell in a range("g2:g" & lastrow) and ("f2:f" & lastrow). The constant value is an active cell in my case. For example considering this formula: IF(AND($R$1<G2;$R$1>=f2);1;0 where R$1$ is the active cell of the last not empty column in ROW 1. I need to fill the entire column (that is activecell.column) with the output coming out form this formula.
But the I Got mismatch error in:
If Range("f2:f" & lastrow) <= Val(CStr(rname.Value)) _
And Range("g2:g" & lastrow) > Val(CStr(rname.Value)) Then
Cells(i, ActiveCell.Column).Value = "1"
Else
Cells(i, ActiveCell.Column).Value = 0
End If
I know from the previous question that this error occurs because I'm trying to comparing a single value against an array of values. How can fix this problem?
You have to use
Range("F" & i)
in your code. Same thing applies to other instances of such code.