I need some help to setup this vba.
I'm looking to add a cell with the date is missing and driver.
for example.
10/29/2018 Name Item driver
10/30/2018 Name Item driver
(add missing date here, no available , no available and driver)
11/02/2018 Name Item driver
if the date is missing and the driver is also missing to add it in.
I hope this helps.
The code below assumes that the values starts at A2 and that all the relevant data is stored in order eg.column B-D. This will insert a row and fill in the data so that every date has an entry. If you have a lot of data to process it might be worthwhile to add in the usual Application.calculation=xlmanual and application.screenupdating = false to speed it up. Just be sure to reset them back to their default states when you're done
Option Explicit
Sub datefiller()
Dim i As Long
Dim lastdate As Long
Dim startDate As Long
Dim TotalRows As Long
i = 2
With ThisWorkbook.Worksheets(1)
While Not IsEmpty(.Range("A" & i).Value)
If Not .Range("A" & i).Value = .Range("A" & i - 1).Value + 1 Then
.Range("A" & i).EntireRow.Insert shift:=xlDown
.Range("A" & i).Value = .Range("A" & i - 1).Value + 1
.Range("B" & i & ":C" & i).Value = "N/A"
.Range("D" & i).Value = "driver"
Else
i = i + 1
End If
Wend
End With
End Sub
EDIT: Adding in the driver's name and accounting for different groupings
Option Explicit
Sub datefiller()
Dim i As Long
Dim lastdate As Long
Dim startDate As Long
Dim TotalRows As Long
i = 3
With ThisWorkbook.Worksheets(1)
While Not IsEmpty(.Range("A" & i).Value)
If (Not .Range("A" & i).Value = .Range("A" & i - 1).Value + 1) And .Range("D" & i).Value = .Range("D" & i - 1).Value Then
.Range("A" & i).EntireRow.Insert shift:=xlDown
.Range("A" & i).Value = .Range("A" & i - 1).Value + 1
.Range("B" & i & ":C" & i).Value = "N/A"
.Range("D" & i).Value = .Range("D" & i - 1).Value
Else
i = i + 1
End If
Wend
End With
End Sub
Related
Thanks for opening my thread. I need help from you.
So in this sheet the total amount should be sum of fuel + surge + delivery_charge should be added in Total amount column.
Ex:- 1st order = 456777 this should add 109.49+303.41+25966.51 = 26379.41
2nd order = 23213213 should add 10+11318+65 = 11393
Dim i As Long, lastrow As Long, rng As Long
lastrow = Range("A" & Rows.Count).End(xlUp).Row
For i = 2 To lastrow
If Cells(i, "A") <> "" Then
rng = Cells(i, "A").End(xlDown).Row - 1
Cells(i, "B").Value = WorksheetFunction.Sum(Range("C" & i & ":C" & rng), Range("E" & i & ":E" & rng), Range("G" & i & ":G" & rng))
End If
Next i
I'm getting output from this logic :
But the issue is for 2nd order id. It should take only that row. But here its taking 5th and 6th row for addition.
2nd order id= 23213213 total_amt should be 11393.
So anyone could you please help me to find out an issue.
Thanks and Regards,
Ranger
The issue is in how you find rng.
rng = Cells(i, "A").End(xlDown).Row - 1
You're using xlDown to find the start of the next block of data. This works as you'd expect, except where the data changes every cell. If you click on cell A5 and press CTRL-Shift-Down, you'll see that it selects three cells as it jumps to the end of that block of data (A7). This is normal Excel behaviour.
You could re-write your code to loop through all the data until it finds the right scenario, but in this case I believe the single cell issue can just be trapped with the right If statement.
If Cells(i + 1, "A") <> "" Then rng = i
Try this:
Dim i As Long, lastrow As Long, rng As Long
lastrow = Range("A" & Rows.Count).End(xlUp).Row
For i = 2 To lastrow
If Cells(i, "A") <> "" Then
rng = Cells(i, "A").End(xlDown).Row - 1
If Cells(i + 1, "A") <> "" Then rng = i
Cells(i, "B").Value = WorksheetFunction.Sum(Range("C" & i & ":C" & rng), Range("E" & i & ":E" & rng), Range("G" & i & ":G" & rng))
End If
Next i
The AE, AG, AH, whenever the D or AD parallel cells are empty, return e.g. date of 00/01/1900 or time as 00:00. Can you please clarify how to return blank if the same parallel cell in D or AD is blank? Thanks
Sub valuedifference()
Dim Total As Double
Dim TimeX As Date
Dim TimeY As Date
Dim LastRow As Long
Dim i As Long
With ThisWorkbook.Sheets("Test1")
LastRow = .Cells(.Rows.Count, "d").End(xlUp).Row
For i = 2 To LastRow
TimeX = CDate(.Range("d" & i).Value)
TimeY = CDate(.Range("ad" & i).Value)
Total = TimeValue(TimeY) - TimeValue(TimeX)
.Range("ae" & i).Value = Total
.Range("ag" & i).Value = Abs(Total * 24)
.Range("ah" & i).Value = Abs(Total * 1440)
Next i
End With
End Sub
I think this a formatting issue- If TimeY is "" and TimeX is "", then
Total = TimeValue(TimeY) - TimeValue(TimeX) is 0.
0 in time format is 0:0:00 and 0 in date format is 00/01/1900
One solution to this is to include an if statement that checks that there are not blank cells
For i = 2 To LastRow
If .Range("D" & i).Value <> "" And .Range("AD" & i).Value <> "" Then
TimeX = CDate(.Range("d" & i).Value)
TimeY = CDate(.Range("ad" & i).Value)
Total = DateDiff("n", TimeY, TimeX)
.Range("AE" & i).Value = Total
.Range("AG" & i).Value = Format(Abs(Total), "#.##")
.Range("AH" & i).Value = Format(Abs(Total), "#.##")
End If
Next i
I have data in B Column of an excel file. I have made a loop that If the value in B Cell is greater than a particular (len1) value, then the code puts the Cell (Value-Len1) value in a new cell at the end of the rows.
I increment the counter as lastrow = lastrow+1 everytime when the row is added. Now here is the problem. Iniitially in the input file I had 122 set of data. But by the time the For loop finishes the value of lastrow becomes 160, but the loop exits at 122. WHY?? Any Help will be appreciated.
For i = 1 To lastrow Step 1
If Range("B" & i).Value > len1 Then
Range("A" & lastrow + 1).Value = Range("A" & i).Value
Range("B" & lastrow + 1).Value = Range("B" & i).Value - len1
Range("B" & i).Value = len1
lastrow = lastrow + 1
End If
Next
To get the behaviour you want you need a while loop (or do loop)
i = 1
While i <= lastrow
If Range("B" & i).Value > len1 Then
lastrow = lastrow + 1
Range("A" & lastrow).Value = Range("A" & i).Value
Range("B" & lastrow).Value = Range("B" & i).Value - len1
Range("B" & i).Value = len1
End If
i = i + 1
Wend
I tested it with the sub below:
Sub LoopBeyondLastRow()
Dim i As Long, lastrow As Long, len1 As Long
len1 = 10
With ThisWorkbook.Sheets("Sheet1")
lastrow = .Cells(Rows.Count, "B").End(xlUp).Row
i = 1
While i <= lastrow
If .Range("B" & i).Value > len1 Then
lastrow = lastrow + 1
.Range("A" & lastrow).Value = .Range("A" & i).Value
.Range("B" & lastrow).Value = .Range("B" & i).Value - len1
.Range("B" & i).Value = len1
End If
i = i + 1
Wend
End With
End Sub
Please note the following:
Inside the loop I incremented lastrow first and then used it in the following 2 statements (to reduce the number of addition operations)
In my test code I added With ThisWorkbook.Sheets("Sheet1") to fully qualify all ranges. Not doing this is the source of many bugs that are sometimes very difficult to pinpoint. One should get in the habbit of never to write Range or Cells without a little . before them.
A faster method would be to export the range values to array and then do the comparision. Store the final output into a temp array and write it back to the worksheet.
If you want to follow your approach then is this what you are trying? I have commented the code so you should not have a problem understanding it. Basically you need 2 loops if you want to recheck the data that you are adding at the end of the row.
Option Explicit
Sub Sample()
Dim ws As Worksheet
Dim ComparisionValue As Long
Dim countOfMatchedValues As Long
Dim lRow As Long
Dim i As Long
Dim outputRow As Long
Dim rng As Range
'~~> Change this to the relevant sheet
Set ws = Sheet1
'~~> Change this to the relevant
'~~> comparision value
ComparisionValue = 122
With ws
'~~> Start an indefinite loop
Do
'~~> Find last row
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
'~~> Fix the output row for the new data
outputRow = lRow + 1
'~~> Check if there are any matches for your condition
countOfMatchedValues = Application.WorksheetFunction.CountIf( _
.Range("B1:B" & lRow), ">" & ComparisionValue)
'~~> If not then exit loop
If countOfMatchedValues = 0 Then Exit Do
'~~> Do your stuff
For i = 1 To lRow
If .Range("B" & i).Value > ComparisionValue Then
.Range("A" & outputRow).Value = .Range("A" & i).Value
.Range("B" & outputRow).Value = .Range("B" & i).Value - ComparisionValue
.Range("B" & i).Value = ComparisionValue
outputRow = outputRow + 1
End If
Next i
Loop
End With
End Sub
In Action
for loops use a pre-defined number of iterations. For an unknown number of iterations you need to use a while loop.
Your code uses the value of lastRow at the time it was interpreted, and is never updated again.
This is similar to:
lastRow = 1
Debug.Print lastRow
lastRow = lastRow + 1
Debug.Print lastRow
You will see:
1
2
and not:
2
2
because once the first Debug statement has been executed, changing the value of lastRow doesn't affect this particular output anymore.
Test the next code, please:
Sub TestLoopAddedRowsInclusive()
'..... your code defining LastRow and len1
Dim lastRInit As Long
lastRInit = LastRow
For i = 1 To Rows.count
If Range("B" & i).Value = "" And i >= lastRInit Then Exit For
If Range("B" & i).Value > len1 Then
Range("A" & LastRow + 1).Value = Range("A" & i).Value
Range("B" & LastRow + 1).Value = Range("B" & i).Value - len1
Range("B" & i).Value = len1
LastRow = LastRow + 1
End If
Next
End Sub
I am trying to copy from Raw Data to Consolidated Data.
If a row in the Raw Data already exists (by checking both the Full Name and the Identity Number together with the AND Condition as the composite key of using both values is unique) in the Consolidated Data it will check through the columns and update it if there are any changes.
For example Ben with the Identity Number of 3333 changed his Contact and Email. So after updating it will have the updated Contact and Email.
Secondly, if the row in the Raw Data doesn't exist it will add to the bottom of the Consolidated Data.
I tried a nested loop for this. I am facing the problem of duplicate entries as my code is checking the row in the Raw Data with every row in the Consolidated Data.
For example in the Raw Data I have Alan (1111), Ben (2222), Ben (3333), Calvin (4444). In the New Consolidated Data I will turn out to have more than four rows after updating.
This is the raw data
This is the old consolidated data
This is the final consolidated data
Dim i As Long, lastRow As Long
Set rawData = sheet1
Set finalData = sheet2
lastRow = sheet1.Cells(rows.Count, "A").End(xlUp).Row
finalLastRow = sheet2.Cells(rows.Count, "A").End(xlUp).Row
MsgBox lastRow
MsgBox finalLastRow
' If the sheet is empty
If (finalLastRow = 2) Then
For i = 3 To lastRow
' Test if cell if empty
If (rawData.range("A" & i).Value <> "") Then
finalData.range("A" & i).Value = rawData.range("A" & i).Value
finalData.rNeange("B" & i).Value = rawData.range("B" & i).Value
finalData.range("C" & i).Value = rawData.range("C" & i).Value
finalData.range("D" & i).Value = rawData.range("D" & i).Value
finalData.range("E" & i).Value = rawData.range("E" & i).Value
End If
Next i
' If the sheet is not empty
ElseIf (finalLastRow <> 2) Then
Dim newLastRow As Long
newLastRow = 4
For i = 3 To lastRow
For j = 3 To finalLastRow
' Test if cell is the same
'Dim matchScore As Long
' Full Name and Identity Number remain same
If (rawData.range("A" & i).Value) = (finalData.range("A" & j).Value) And (rawData.range("B" & i).Value) = (finalData.range("B" & j).Value) Then
finalData.range("C" & j).Value = rawData.range("C" & i).Value
finalData.range("D" & j).Value = rawData.range("D" & i).Value
finalData.range("E" & j).Value = rawData.range("E" & i).Value
MsgBox "SAME"
' New Record
Else
' Check through the sheet2 to see if the row have been added to it
newLastRow = newLastRow + 1
finalData.range("B" & newLastRow).Value = rawData.range("B" & i).Value
End If
finalLastRow = sheet2.Cells(rows.Count, "A").End(xlUp).Row
Next j
Next i
End If
I have added another For loop in the Else statement to check through the columns to see if it exists.
' New Record
Else
Dim isDataInCurrentRows As Boolean
isDataInCurrentRows = False
For checkRow = 3 To finalLastRow
If (rawData.range("B" & i).Value) = (finalData.range("B" & checkRow).Value) And (rawData.range("D" & i).Value) = (finalData.range("D" & checkRow).Value) Then
isDataInCurrentRows = True
Exit For
End If
Next checkRow
If isDataInCurrentRows = False Then
finalData.range("A" & finalLastRow + 1).Value = rawData.range("A" & i).Value
finalData.range("B" & finalLastRow + 1).Value = rawData.range("B" & i).Value
finalData.range("C" & finalLastRow + 1).Value = rawData.range("C" & i).Value
finalData.range("D" & finalLastRow + 1).Value = rawData.range("D" & i).Value
finalData.range("E" & finalLastRow + 1).Value = rawData.range("E" & i).Value
finalData.range("F" & finalLastRow + 1).Value = rawData.range("F" & i).Value
finalData.range("G" & finalLastRow + 1).Value = rawData.range("G" & i).Value
finalData.range("H" & finalLastRow + 1).Value = rawData.range("H" & i).Value
finalData.range("I" & finalLastRow + 1).Value = Date
End If
End If
I have an excel sheet which need do format the data
I need to format this data like this in different sheet
Note - This a small sample I created for your understanding
my test macro is below. If you want to use it, you just need to rename your sheets - "DataSheet" for the one with the data and "ResultSheet" where the result will be stored.
Sub Reformat()
Dim letter As String
Dim iRow As Integer
Dim rng As Excel.Range
Sheets("ResultSheet").Range("A1:A" & Range("A1").End(xlDown).Row).Value = Range("A1:A" & Range("A1").End(xlDown).Row).Value
Sheets("ResultSheet").Select
Range("A1:A" & Range("A1").End(xlDown).Row).RemoveDuplicates Columns:=1, Header:=xlNo
Set rng = Range("A1:A" & Range("A1").End(xlDown).Row)
For i = 1 To Sheets("DataSheet").Range("A1").End(xlDown).Row
letter = Sheets("DataSheet").Range("A" & i).Value
iRow = WorksheetFunction.Match(letter, rng)
If Range("B" & iRow).Value = "" Then
Range("B" & iRow).Value = Sheets("DataSheet").Range("B" & i).Value
Else
Range("A" & iRow).End(xlToRight).Offset(0, 1).Value = Sheets("DataSheet").Range("B" & i).Value
End If
Next i
End Sub