Looping over Visible Range Issue - vba

The function is supposed to loop over a filtered range appending a certain date to the first "i" lines then moving to the next date and repeating.
It is appending everything to the header instead of moving down a row each time.
It is not erroring, just not acting as expected. Where am I going wrong on this?
Sub Function()
Dim wsExport As Worksheet
Set wsExport = Workbooks("Export Workbook").Worksheets("Export")
Dim uiStartDate As Variant 'I'm using the prefix ui to be User Input
Dim uiEndDate As Variant
Dim uiCount As Variant
Dim cStartDate As Long 'Converted to date
Dim cEndDate As Long
Dim cCount As Long
Dim iDate As Long 'Counter for the date
Dim i As Long 'Counter for the number of items per day.
Dim j As Long 'Counter for Rows
Dim lRow As Long
lRow = Cells.Find(What:="*", LookAt:=xlPart, _
LookIn:=xlFormulas, SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, MatchCase:=False).Row
'Prompt the user for the start date and end date
'uiStartDate = InputBox("Input the first day of week in the format of 01/20/2018", "Start Date User Input")
'uiEndDate = InputBox("Input the last day of week in the format of 01/25/2018", "End Date User Input")
'uiCount = InputBox("Input the number of items per day.", "Installtion Quantity User Input")
uiStartDate = "1/20/2018" 'This is to speed during testing. Will use the above for actual code
uiEndDate = "1/25/2018"
uiCount = "2"
'Convert to their proper data types. (User inputs have to be variants to begin with)
cStartDate = CDate(uiStartDate)
cEndDate = CDate(uiEndDate)
cCount = CLng(uiCount)
With wsExport.Range("A:AP")
.AutoFilter Field:=19, Criteria1:=">=" & uiStartDate
End With
iDate = cStartDate
j = 2
i = 1
Do While j <= lRow
DoEvents
If Not wsExport.Rows(j).Hidden Then
wsExport.Range("S" & j).Value = wsExport.Range("S" & j).Value & "-" & iDate
i = i + 1
End If
If i > cCount Then
i = 1
iDate = iDate + 1
End If
If iDate > cEndDate Then
j = lRow + 1
End If
j = j + 1
Loop
End Sub

Here's a simplified example using a different approach to looping over the table:
EDIT: updated to your actual process of incrementing the date every two rows...
Sub Tester()
Dim sht As Worksheet, rngTable As Range, rw As Range, r As Long
Dim sDate, eDate, dt, i As Long
Set sht = ActiveSheet
Set rngTable = sht.Range("A1").CurrentRegion
rngTable.AutoFilter 'clear any previous filter
rngTable.AutoFilter field:=4, Criteria1:=">3" 'filter to required rows only
'some dates...
sDate = Date
eDate = Date + 3
dt = sDate 'set date to add
i = 0
For r = 2 To rngTable.Rows.Count
Set rw = rngTable.Rows(r)
'is the row visible?
If Not rw.Hidden Then
With rw.Cells(2)
.Value = .Value & " - " & Format(dt, "dd/mm/yyyy")
End With
i = i + 1
If i Mod 2 = 0 Then dt = dt + 1 '<< next date every 2 visible rows
If dt > eDate Then Exit For '<< exit if run out of dates
End If
Next r
End Sub

xlCellTypeVisible does not do what you want when working with an offset from a cell like this. Just use an IF instead:
For i = 1 To cCount
currentRow = currentCell.Offset(1, 0).Row
Set currentCell = wsExport.Range("S" & currentRow)
if currentcell.rowheight > 0 then currentCell.Value = currentCell.Value & "- " & iDate
Next i

Related

How to one date per row for all dates between 2 dates?

I know this question seem complicated but what I want to do is simple, I got 2 columns:
I is my Starting Date
L is my ending date
G is where all the dates are supposed to be
What I want to do is get the number of days per period (EndDate - StartDate + 1), add this many rows and change value of G to be written day per day.
I already coded the part below, but it doesn't seem to be right:
Sub Dates()
Dim LastRow As Long
Dim addrows
Dim FindDates
Dim CountDays
Dim dddays
Dim ws As Worksheet
Dim ws2 As Worksheet
Dim i As Long
Dim ir As Long
Set ws = Sheets("Sheet1")
Set ws2 = Sheets("Sheet2")
With Sheets("Sheet1")
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row - 1
End With
addrows = 2
For ir = 1 To LastRow
FindDates = ws.Range("I" & addrows).Value
CountDays = ws.Range("L" & addrows).Value - ws.Range("I" & addrows).Value + 1
Adddays = 0
For i = 1 To CountDays
ws2.Rows("2:2").Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
ws2.Range("A2").Value = Sheets("Sheet1").Range("A" & addrows).Value
ws2.Range("C2").Value = FindDates + Adddays
ws2.Range("C2").Value = ws.Range("G" & addrows).Value
Adddays = Adddays + 1
Next i
addrows = addrows + 1
Next ir
End Sub
File looks as follows:
Can you help me a bit? "ws2.Range("C2").Value = FindDates + Adddays" is giving me an error 13
I is my Starting Date
L is my ending date
G is where all the dates are supposed to be
What I want to do is get the number of days per period (EndDate - StartDate + 1), add this many rows and change value of G to be written day per day.
for what above this should help you:
Sub Dates()
Dim ir As Long, countDays As Long
With Sheets("Sheet1")
For ir = .Cells(.Rows.Count, "I").End(xlUp).row To 2 Step -1
With .Rows(ir)
countDays = .range("L1") - .range("I1") + 1
If countDays > 1 Then
.Offset(1).Resize(countDays - 1).Insert xlDown
.Offset(1).Resize(countDays - 1).value = .value
With .Resize(countDays).Columns("G")
.FormulaR1C1 = "=RC9+ROW()-" & .Rows(1).row
.value = .value
End With
End If
End With
Next
End With
End Sub

With the code below I receive the error Variable not defined

Columns A, D and E are date and time.
I am trying to find out how many times the date in Column A falls between the start dates and end dates.
Column A may vary between 30 and 60 days while the start and end dates run to thousands.
Two questions:
Why am I receiving error Variable Not defined with the code below?
If cell A2 is date and time 24Feb17 12H00 then what formula do I put in cell A3 so that it reads 25Feb17 12H00 and so on?
Code:
Option Explicit
Sub DaysCount()
Dim endRow As Long
Dim LastRow As Long
Dim ICount As Long
Dim Day() As Variant
Dim StartDate() As Variant
Dim EndDate() As Variant
ICount = 0
With ThisWorkbook.Worksheets("sheet1")
LastRow = .Range("A" & .Rows.count).End(xlUp).Row
endRow = .Range("D" & .Rows.count).End(xlUp).Row
Day = Sheet1.Range("A2:A" & LastRow)
StartDate = Sheet1.Range("D2:D" & endRow)
EndDate = Sheet1.Range("E2:E" & endRow)
For i = LBound(StartDate) To UBound(StartDate)
For J = LBound(Day) To UBound(Day)
If Day(J, 1) >= StartDate(i, 1) And Day(J, 1) <= EndDate(i, 1) Then
ICount = ICount + 1
Else
End If
Sheet1.Range("B" & J).Value = ICount
Next i
ICount = 0
Next J
End With
End Sub
Option Explicit forces you to declare all variables, so you need to declare i and j too.
And your Next i and Next j weren't in the good order!
VBA : DateAdd("d",.Range("A3"),1)
Corrected code:
Option Explicit
Sub DaysCount()
Dim i As Long
Dim j As Long
Dim endRow As Long
Dim LastRow As Long
Dim ICount As Long
Dim Day() As Variant
Dim StartDate() As Variant
Dim EndDate() As Variant
ICount = 0
With ThisWorkbook.Worksheets("sheet1")
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
endRow = .Range("D" & .Rows.Count).End(xlUp).Row
Day = Sheet1.Range("A2:A" & LastRow)
StartDate = Sheet1.Range("D2:D" & endRow)
EndDate = Sheet1.Range("E2:E" & endRow)
For i = LBound(Day) To UBound(Day)
For j = LBound(StartDate) To UBound(StartDate)
If Day(j, 1) >= StartDate(i, 1) And Day(j, 1) <= EndDate(i, 1) Then
ICount = ICount + 1
Else
End If
Next j
.Range("B" & i).Value = ICount
ICount = 0
Next i
End With
End Sub

VBA Countifs error

I have a bit of code I've written and I'm having trouble with a certain line (Countifs statement). I haven't ever used this in VBA before so I think it might be something to do with Syntax? Please could someone take a look and let me know?
Thanks very much!
Sub TradeCopy()
'Declare Variables
Dim x As Worksheet
Dim y As Worksheet
Dim z As Range
Dim FirstRow As Integer
Dim LastRow As Long
Dim i As Long
Dim j As Long
Dim s As String
Dim t As String
Dim count As Long
Dim startdate As Long
On Error GoTo ERROREND
Application.DisplayAlerts = False
Application.EnableEvents = False
'Setting Values
s = ActiveWorkbook.Sheets("Name Creator").Range("B4")
Set x = ActiveWorkbook.Sheets(s)
t = ActiveWorkbook.Sheets("Name Creator").Range("B5")
Set y = ActiveWorkbook.Sheets(t)
startdate = ActiveWorkbook.Sheets("Name Creator").Range("B3")
'Find Cell where name occurs
Set z = x.Columns("A").Find(what:="trade id", LookIn:=xlValues, Lookat:=xlWhole)
'Return Start Row number
FirstRow = z.Row + 1
'Return Last Row number
LastRow = x.Range("A" & Rows.count).End(xlUp).Row
'Clear Existing Range of Values
y.Rows(2 & ":" & Rows.count).ClearContents
Below is the code giving problems, specifically the "count = " line when running debugger.
'Loop to highlight cells based on conditions
For i = FirstRow To LastRow
count = Application.WorksheetFunction.CountIfs(x.Range("B:B"), x.Range(i, 2), x.Range("L:L"), "<" & startdate)
Rest of code:
If (x.Cells(i, 21) = "Fra" Or x.Cells(i, 21) = "Swap" Or x.Cells(i, 21) = "Swaption" Or x.Cells(i, 21) = "BondOption" Or x.Cells(i, 21) = "CapFloor") And DateValue(x.Cells(i, 12).Value) > startdate And count <= 0 Then
x.Rows.Range("A" & i).Value.Interior.Color = vbRed
End If
Next i
'Loop to check for all 0 Cells and paste values
For j = FirstRow To LastRow
If x.Cells(j, 1).Interior.Color = vbRed Then
x.Rows.Range("A" & j).Value = y.Rows.Range("A" & j).Value
End If
Next j
'Remove Duplicates
y.Columns(2).RemoveDuplicates Columns:=Array(1)
Application.DisplayAlerts = True
Application.EnableEvents = True
MsgBox ("All Done!")
Exit Sub
ERROREND:
MsgBox ("Unexpected Error - Please Seek Assistance or Debug Code")
End Sub
I think you need to change .Range to .Cells in below:
count = Application.WorksheetFunction.CountIfs(x.Range("B:B"), x.Range(i, 2), x.Range("L:L"), "<" & startdate)
To:
count = Application.WorksheetFunction.CountIfs(x.Range("B:B"), x.Cells(i, 2), x.Range("L:L"), "<" & startdate)

Extracting and copying data in an excel file

I'm extracting data froman excel file that is inside the parameter of the dates provided. But this code is not working. Anybody can help me figure this out?
Set src = wb.Sheets("Request Log Extract")
Set dest = ThisWorkbook.Sheets("Resolution Time Performance")
srcRow = src.Cells(src.Rows.Count, "K").End(xlUp).Row
destRow = dest.Cells(dest.Rows.Count, "E").End(xlUp).Row + 1
wb.Activate
For i = 2 To srcRow
If src.Cells("K" & i) >= txtStartDate.Value Or src.Cells("K" & i) <= .txtEndDate.Value Then
src.Cells("K" & i).Copy
dest.Activate
dest.Cells("E" & i).Paste
src.Activate
End If
Next
This returns an error saying :
Invalid procedure call or argument.
NOTE
txtStartDate and txtEndDate are date Types.
If I use OR in the If condition, all data were copied, but if I used And, no data is copied. I don't know whats going on.
VALUES
txtStartDate 05/13/2016
txtEndDate 05/18/2016
k2 05/14/2016
Im not sure with your txtStartDate and txtEndDate variables, but look at my code
I declared your variables, but please specify date types, also i removed dot from txtEndDate and changed cell references and now it works.
Sub extractData()
Dim src
Dim dest
Dim wb As Workbook
Set wb = ThisWorkbook
Dim txtStartDate
Dim txtEndDate
Set src = wb.Sheets("Request Log Extract")
Set dest = ThisWorkbook.Sheets("Resolution Time Performance")
srcRow = src.Cells(src.Rows.Count, "K").End(xlUp).Row
destRow = dest.Cells(dest.Rows.Count, "E").End(xlUp).Row + 1
txtStartDate = 0
txtEndDate = 100
For i = 2 To srcRow
If src.Cells(i, "K").Value > txtStartDate Or src.Cells(i, "K").Value < txtEndDate Then
src.Cells(i, "K").Copy
dest.Activate
dest.Cells(i, "E").PasteSpecial
src.Activate
End If
Next
End Sub
I think it's a date value issue
Moreover I'm guessing your code is within some userform pane and activated at some button click after which it has to compare two textboxes values to some cells content and copy/paste values accordingly
should my guessing be right (finger crossed...) try this:
Option Explicit
Private Sub CommandButton1_Click()
Dim src As Worksheet, dest As Worksheet
Dim srcRow As Long, destRow As Long, i As Long
Dim startDate As Date, endDate As Date, cellDate As Date
With Me
If Not ValidateDate("txtStartDate", .txtStartDate.Value, startDate) Then Exit Sub
If Not ValidateDate("txtEndDate", .txtEndDate.Value, endDate) Then Exit Sub
Set src = ActiveWorkbook.Sheets("Request Log Extract") '<~~ change workbook reference as per your need
Set dest = ThisWorkbook.Sheets("Resolution Time Performance")
srcRow = src.Cells(src.Rows.Count, "K").End(xlUp).Row
destRow = dest.Cells(dest.Rows.Count, "E").End(xlUp).Row + 1
For i = 2 To srcRow
If ValidateDate("src.Range(""K" & i & """)", src.Range("K" & i), cellDate) Then
If cellDate >= startDate And cellDate <= endDate Then src.Range("K" & i).Copy dest.Range("E" & i)
End If
Next
End With
End Sub
Function ValidateDate(textName As String, textValue As String, retDate As Date) As Boolean
ValidateDate = IsDate(textValue)
If ValidateDate Then
retDate = DateValue(textValue)
Else
MsgBox textValue & " is not a valid date" & vbCrLf & "please input a new value for " & textName
End If
End Function
should my guessing be wrong, still the code above can give you some suggestions as to the date value issue
This code is working for me:
Sub Demo()
Dim wb As Workbook
Dim txtStartDate As Date, txtEndDate As Date
Set wb = ActiveWorkbook
Set src = wb.Sheets("Request Log Extract")
Set dest = wb.Sheets("Resolution Time Performance")
srcRow = src.Cells(src.Rows.Count, "K").End(xlUp).Row
destRow = dest.Cells(dest.Rows.Count, "E").End(xlUp).Row + 1
txtStartDate = "05/13/2016"
txtEndDate = "05/18/2016"
For i = 2 To srcRow
If src.Range("K" & i).Value >= txtStartDate And src.Range("K" & i).Value <= txtEndDate Then
src.Range("K" & i).Copy Destination:=dest.Range("E" & i)
End If
Next
End Sub

Lookup dates and calculate expiratrion

I have two data reports where I sort the data in data report 1 and move it to a sheet called "List". To finish off the report I then,
Get a date from data report two for every line I have in the sorted list. To do this I have tried to take the action title in column "G" in the sheet "List" and then I search for it in the sheet "Data2" in column "C", then I return the row number and want to save a number there is in the column "G". This number is the days to deadline and can either be a positive or negative number.
Take today's date + / - the number and put the modified date and the sheet "Lists" in column "N" to be able to see when every task has deadline.
I can't get other kinds of data in the reports so I have to solve this with some VBA. The code I have tried is this.
Sub InsertDate()
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim i As Integer
Dim RowNr As Long
Dim ActionTitle As String
Dim DaysToExp As Long
Dim ExpDate As Date
Dim Found As Range
Dim FoundRow As Long
Dim Sign As String
Dim Days As String
Dim RowNr2 As Long
ScreenUpdate = False
RowNr = ThisWorkbook.Worksheets("List").Range("A" & Rows.count).End(xlUp).row
RowNr2 = ThisWorkbook.Worksheets("Data2").Range("A" & Rows.count).End(xlUp).row
Set ws1 = ThisWorkbook.Worksheets("List")
Set ws2 = ThisWorkbook.Worksheets("Data2")
ws1.Range("N1").Value = "Expected start date"
For i = 2 To RowNr
ActionTitle = ws1.Range("G" & i).Value
Set Found = ws2.Range("C1:C" & RowNr2).Find(What:=ActionTitle, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows).Activate
FoundRow = ActiveCell.row
Days = ws2.Range("G" & FoundRow).Value
If Days = "" Then
DaysToExp = DaysToExp + 0
ElseIf Left(Days, 1) = "-" Then
Sign = "-"
DaysToExp = Replace(Days, "-", "")
Else
Sign = "+"
DaysToExp = DaysToExp + Days
End If
ExpDate = "=TODAY() & Sign & DaysToExp"
ThisWorkbook.Worksheets("List").Range("N" & i).Value = ExpDate
Next i
ScreenUpdate = True
End Sub
I've tightened up your code a bit and removed the .Find in place of a worksheet function .Match. You don't need to parse out the sign of Days since you can add a negative number to the date.
Sub InsertDate()
Dim ws1 As Worksheet, ws2 As Worksheet
Dim i As Long
Dim RowNr As Long, DaysToExp As Long, FoundRow As Long, RowNr2 As Long
Dim ActionTitle As String, Sign As String, Days As String
Dim ExpDate As Date
Dim Found As Range
Application.ScreenUpdating = False
Set ws1 = ThisWorkbook.Worksheets("List")
Set ws2 = ThisWorkbook.Worksheets("Data2")
RowNr2 = ws2.Range("A" & Rows.Count).End(xlUp).Row
With ws1
RowNr = .Range("A" & Rows.Count).End(xlUp).Row
.Range("N1").Value = "Expected start date"
For i = 2 To RowNr
ActionTitle = ws1.Range("G" & i).Value
If CBool(Application.CountIf(ws2.Range("C1:C" & RowNr2), ActionTitle)) Then
FoundRow = Application.Match(ActionTitle, ws2.Range("C1:C" & RowNr2), 0)
Days = ws2.Range("G" & FoundRow).Value
ExpDate = Date + Days
.Range("N" & i).Value = ExpDate
Else
Debug.Print "missing " & ActionTitle
End If
Next i
End With
Application.ScreenUpdating = True
End Sub
I threw a debug.print in that will report to the VBE's Immediate window if ActionTitle cannot be found.