With the code below I receive the error Variable not defined - vba

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

Related

Combining consecutive values in a column with the help of VBA

I have a data like this :
A049
A050
A051
A053
A054
A055
A056
A062
A064
A065
A066
And I want the output like :
As you can see, I want the ranges which are in consecutive order
I am trying some thing like this:
Private Sub CommandButton1_Click()
Set wb = ThisWorkbook
lastRow = wb.Sheets("Sheet1").Range("A" & wb.Sheets("Sheet1").Rows.Count).End(xlUp).Row
For i = 2 To lastRow
r = wb.Sheets("Sheet1").Range("A" & i).Value
If wb.Sheets("Sheet1").Range("A" & i).Value = wb.Sheets("Sheet1").Range("A" & i+1).Value
Next i
End Sub
But not helping me
Am feeling charitable so have tried some code which should work. It assumes your starting values are in A1 down and puts results in C1 down.
Sub x()
Dim v1, v2(), i As Long, j As Long
v1 = Range("A1", Range("A" & Rows.Count).End(xlUp)).Value
ReDim v2(1 To UBound(v1, 1), 1 To 2)
For i = LBound(v1, 1) To UBound(v1, 1)
j = j + 1
v2(j, 1) = v1(i, 1)
If i <> UBound(v1, 1) Then
Do While Val(Right(v1(i + 1, 1), 3)) = Val(Right(v1(i, 1), 3)) + 1
i = i + 1
If i = UBound(v1, 1) Then
v2(j, 2) = v1(i, 1)
Exit Do
End If
Loop
End If
If v1(i, 1) <> v2(j, 1) Then v2(j, 2) = v1(i, 1)
Next i
Range("C1").Resize(j, 2) = v2
End Sub
Try the below code
Private Sub CommandButton1_Click()
Set wb = ThisWorkbook
lastRow = wb.Sheets("Sheet1").Range("A" & wb.Sheets("Sheet1").Rows.Count).End(xlUp).Row
Dim lastNum, Binsert As Integer
Dim firstCell, lastCell, currentCell As String
Binsert = 1
lastNum = getNum(wb.Sheets("Sheet1").Range("A1").Value)
firstCell = wb.Sheets("Sheet1").Range("A1").Value
For i = 2 To lastRow
activeNum = getNum(wb.Sheets("Sheet1").Range("A" & i).Value)
currentCell = wb.Sheets("Sheet1").Range("A" & i).Value
If (activeNum - lastNum) = 1 Then
'nothing
Else
lastCell = wb.Sheets("Sheet1").Range("A" & (i - 1)).Value
wb.Sheets("Sheet1").Range("B" & Binsert).FormulaR1C1() = firstCell
If (firstCell <> lastCell) Then
wb.Sheets("Sheet1").Range("C" & Binsert).FormulaR1C1() = lastCell
End If
Binsert = Binsert + 1
firstCell = wb.Sheets("Sheet1").Range("A" & i).Value
End If
lastNum = activeNum
Next i
'last entry
wb.Sheets("Sheet1").Range("B" & Binsert).FormulaR1C1() = firstCell
If (firstCell <> currentCell) Then
wb.Sheets("Sheet1").Range("C" & Binsert).FormulaR1C1() = currentCell
End If
End Sub
Public Function getNum(ByVal num As String) As Integer
getNum = Val(Mid(num, 2))
End Function
Another solution. It loops backwards from last row to first row.
Option Explicit
Public Sub FindConsecutiveValues()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1")
Dim lRow As Long 'find last row
lRow = ws.Range("A" & ws.Rows.Count).End(xlUp).Row
Dim lVal As String 'remember last value (stop value)
lVal = ws.Range("A" & lRow).Value
Const fRow As Long = 2 'define first data row
Dim i As Long
For i = lRow To fRow Step -1 'loop from last row to first row backwards
Dim iVal As Long
iVal = Val(Right(ws.Range("A" & i).Value, Len(ws.Range("A" & i).Value) - 1)) 'get value of row i without A so we can calculate
Dim bVal As Long
bVal = 0 'reset value
If i <> fRow Then 'if we are on the first row there is no value before
bVal = Val(Right(ws.Range("A" & i - 1).Value, Len(ws.Range("A" & i - 1).Value) - 1)) 'get value of row i-1 without A
End If
If iVal - 1 = bVal Then
ws.Rows(i).Delete 'delete current row
Else
If lVal <> ws.Range("A" & i).Value Then 'if start and stop value are not the same …
ws.Range("B" & i).Value = lVal 'write stop value in column B
End If
lVal = ws.Range("A" & i - 1).Value 'remember now stop value
End If
Next i
End Sub

Looping over Visible Range Issue

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

Add data in next available row

This Macro adds data in Cell A10. Now the data gets overwritten every time i run it again. How can i add 1 cel below?
Sub Invoer()
Dim Debiteurnummer As Integer
Dim Aantalpallets As Integer
Dim Totaalgewicht As Integer
Debiteurnummer = InputBox("Debiteurnummer invoeren")
Aantalpallets = InputBox("Aantal Pallets?")
Totaalgewicht = InputBox("Totaal Gewicht?")
Range("A10").Value = Debiteurnummer
Range("A10").Offset(0, 2) = Aantalpallets
Range("A10").Offset(0, 3) = Totaalgewicht
End Sub
Add a dynamic search for LastRow:
Sub Invoer()
Dim Debiteurnummer As Integer
Dim Aantalpallets As Integer
Dim Totaalgewicht As Integer
Dim LastRow As Long
Debiteurnummer = InputBox("Debiteurnummer invoeren")
Aantalpallets = InputBox("Aantal Pallets?")
Totaalgewicht = InputBox("Totaal Gewicht?")
LastRow = Cells(Rows.count, "A").End(xlUp).row
Range("A" & LastRow + 1).Value = Debiteurnummer
Range("A" & LastRow + 1).Offset(0, 2) = Aantalpallets
Range("A" & LastRow + 1).Offset(0, 3) = Totaalgewicht
End Sub

Deleting Duplicate Row. (Type Mismatch error)

I'm getting type mismatch error on Line "If Not LRow = Range("C65536").End(xlUp).Row = "" Then"
Private Sub DEDUPLICATE_Click()
Application.ScreenUpdating = False
Dim n As Long
Dim LRow As Long
If Not LRow = Range("C65536").End(xlUp).Row = "" Then
LRow = Range("C65536").End(xlUp).Row
For n = LRow To 6 Step -1
If Application.WorksheetFunction.CountIf(Range("C6:C" & n), Range("C" & n).Text) > 1 Then
Range("C" & n).EntireRow.Delete
End If
Next n
End If
This code should delete all duplicate entity excluding the empty rows. Tried to change the data type from Long to Variant but it deletes all rows including the empty ones.
Try this:
Private Sub DEDUPLICATE_Click()
Application.ScreenUpdating = False
Dim n As Long
Dim LRow As Long
LRow = Range("C65536").End(xlUp).Row
For n = LRow To 6 Step -1
If Application.WorksheetFunction.CountIf(Range("C6:C" & n), Range("C" & n).Text) > 1 Then
If Not Range("C" & n).Value = "" Then
Range("C" & n).EntireRow.Delete
End If
End If
Next n
End Sub
Its because the rows count is a numeric value and you are comparing it with a string
Private Sub DEDUPLICATE_Click()
Application.ScreenUpdating = False
Dim n As Long
Dim LRow As Long
If Not LRow = Range("C65536").End(xlUp).Row = 0 Then
LRow = Range("C65536").End(xlUp).Row
For n = LRow To 6 Step -1
If Application.WorksheetFunction.CountIf(Range("C6:C" & n), Range("C" & n).Text) > 1 Then
Range("C" & n).EntireRow.Delete
End If
Next n
End If
End Sub
Thanks

Copy row plus next 3

I have the below code that works great. It parses through all my sheets and finds the row in column A that I want and pastes it to a specified worksheet. However, I need it to copy the specified row plus the next X number of rows. Can someone help me accomplish this?
Sub FindValues()
Dim ws As Excel.Worksheet
Dim LastRow As Long
Dim i As Integer
For Each ws In Application.ThisWorkbook.Worksheets
LastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row
i = 1
Do While i <= LastRow
If ws.Range("A" & i).Value = "OwnershipType Ownership Type" Then
ws.Rows(i).Copy Sheets("Summary").Range("A2")
i = i - 1
LastRow = LastRow - 1
End If
i = i + 1
Loop
Next
End Sub
You can amend the range of rows being copied on this line like so:
ws.Rows(i & ":" & i + 3).Copy Sheets("Summary").Range("A2")
If the match was found in row 1 for example, the code would render as ws.Rows(1:4).Copy
I have done some minor modifications. Just added (i + number of rows to be copied). Check the below code:
Used Integer copyrw in the code, you can set this integer to copy the number of rows.
Sub FindValues()
Dim ws As Excel.Worksheet
Dim LastRow As Long
Dim i As Integer
Dim copyrw as Integer
copyrw = 3
For Each ws In Application.ThisWorkbook.Worksheets
LastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row
i = 1
Do While i <= LastRow
If ws.Range("A" & i).Value = "OwnershipType Ownership Type" Then
ws.Rows(i & ":" & i + copyrw).Copy Sheets("Summary").Range("A2")
i = i - 1
LastRow = LastRow - 1
End If
i = i + 1
Loop
Next
End Sub