Hi all I hope you can help. I have a piece of code see below.
What I am trying to achieve is that a user opens up an Excel sheet that contains a command button and instructions.
Once the command button is clicked a dialog box opens up which then allows the user to select another excel sheet, once that excel sheet is selected another piece of code (should) fire and duplicates are consolidated and start dates and end dates are amended, and the sheet is left open in its desired state free of duplicates and dates correct.
The piece of code
Public Sub ConsolidateDupes()
works perfectly when it is run by itself, on the original sheet but when I try to call it with the command button , its is not working correctly. No error appears it just does not remove all the possible duplicates and does not work the dates to the earliest start and latest end date
I have added pictures to make explanation easier
Pic 1
Excel sheet with Command Button
Pic 2 the Sheet to be selected in its original state with Duplicates and multiple start and end dates
The selected sheet after code has been run by itslef on that sheet
The selected sheet when it is called when command button is used
As you can hopefully see the Duplicates are left and the dates are not worked to the earliest start date and latest end date
As i said the code works perfectly when run on the sheet by itself but when it is called it leaves duplicates and is not working the start and end dates
Here is my code any help is as always greatly appreciated.
CODE
Sub Open_Workbook_Dialog()
Dim my_FileName As Variant
MsgBox "Select Denmark File" '<--| txt box for prompt to pick a file
my_FileName = Application.GetOpenFilename(FileFilter:="Excel Files,*.xl*;*.xm*") '<--| Opens the file window to allow selection
If my_FileName <> False Then
Workbooks.Open Filename:=my_FileName
Call ConsolidateDupes '<--|Calls the Filter Code and executes
End If
End Sub
Public Sub ConsolidateDupes()
Dim wks As Worksheet
Dim lastRow As Long
Dim r As Long
Set wks = Sheet1
lastRow = wks.UsedRange.Rows.Count
For r = lastRow To 3 Step -1
' Identify Duplicate
If wks.Cells(r, 1) = wks.Cells(r - 1, 1) _
And wks.Cells(r, 2) = wks.Cells(r - 1, 2) _
And wks.Cells(r, 3) = wks.Cells(r - 1, 3) _
And wks.Cells(r, 4) = wks.Cells(r - 1, 4) _
And wks.Cells(r, 5) = wks.Cells(r - 1, 5) _
And wks.Cells(r, 6) = wks.Cells(r - 1, 6) _
And wks.Cells(r, 7) = wks.Cells(r - 1, 7) Then
' Update Start Date on Previous Row
If wks.Cells(r, 8) < wks.Cells(r - 1, 8) Then
wks.Cells(r - 1, 8) = wks.Cells(r, 8)
End If
' Update End Date on Previous Row
If wks.Cells(r, 9) > wks.Cells(r - 1, 9) Then
wks.Cells(r - 1, 9) = wks.Cells(r, 9)
End If
' Delete Duplicate
Rows(r).Delete
End If
Next
End Sub
Can you delete this:
Rows(r).Delete
And write this instead:
wks.Rows(r).Delete
Edit:
Try this:
(very dirty solution, but it should work)
Sub Open_Workbook_Dialog()
Dim strFileName As string
dim wkb as workbook
Dim wks As Worksheet
Dim lastRow As Long
Dim r As Long
MsgBox "Select Denmark File" '<--| txt box for prompt to pick a file
strFileName = Application.GetOpenFilename(FileFilter:="Excel Files,*.xl*;*.xm*") '<--| Opens the file window to allow selection
set wkb = Application.Workbooks.Open(strFileName)
Set wks = wkb.Sheet1
lastRow = wks.UsedRange.Rows.Count
For r = lastRow To 3 Step -1
' Identify Duplicate
If wks.Cells(r, 1) = wks.Cells(r - 1, 1) _
And wks.Cells(r, 2) = wks.Cells(r - 1, 2) _
And wks.Cells(r, 3) = wks.Cells(r - 1, 3) _
And wks.Cells(r, 4) = wks.Cells(r - 1, 4) _
And wks.Cells(r, 5) = wks.Cells(r - 1, 5) _
And wks.Cells(r, 6) = wks.Cells(r - 1, 6) _
And wks.Cells(r, 7) = wks.Cells(r - 1, 7) Then
' Update Start Date on Previous Row
If wks.Cells(r, 8) < wks.Cells(r - 1, 8) Then
wks.Cells(r - 1, 8) = wks.Cells(r, 8)
End If
' Update End Date on Previous Row
If wks.Cells(r, 9) > wks.Cells(r - 1, 9) Then
wks.Cells(r - 1, 9) = wks.Cells(r, 9)
End If
' Delete Duplicate
Rows(r).Delete
End If
Next
End Sub
However, the problem is that it did not work, because you did not pass the my_FileName to the ConsolidateDupes procedure. Thus, the procedure was executing in the file with the button, and it was a bit meaningless there.
Hi so some changes were need to get this to work and the code that works is below I hope it helps a fellow VBA'r out :-)
Sub Open_Workbook_Dialog()
Dim strFileName As String
Dim wkb As Workbook
Dim wks As Worksheet
Dim LastRow As Long
Dim r As Long
MsgBox "Select Denmark File" '<--| txt box for prompt to pick a file
strFileName = Application.GetOpenFilename(FileFilter:="Excel Files,*.xl*;*.xm*") '<--| Opens the file window to allow selection
Set wkb = Application.Workbooks.Open(strFileName)
Set wks = ActiveWorkbook.Sheets(1)
LastRow = wks.UsedRange.Rows.Count
' Sort the B Column Alphabetically
With ActiveWorkbook.Sheets(1)
Dim LastRow2 As Long
LastRow2 = .Cells(Rows.Count, 1).End(xlUp).Row
Dim LastCol As Long
LastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
With ActiveWorkbook.Worksheets("Sheet1").Sort
.SortFields.Clear
.SortFields.Add Key:=Range(Cells(2, 2), Cells(LastRow, 2)), _
SortOn:=xlSortOnValues, _
Order:=xlAscending, _
DataOption:=xlSortNormal
.SetRange Range(Cells(2, 1), Cells(LastRow, LastCol))
.Header = xlNo
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End With
For r = LastRow To 3 Step -1
' Identify Duplicate
If wks.Cells(r, 1) = wks.Cells(r - 1, 1) _
And wks.Cells(r, 2) = wks.Cells(r - 1, 2) _
And wks.Cells(r, 3) = wks.Cells(r - 1, 3) _
And wks.Cells(r, 4) = wks.Cells(r - 1, 4) _
And wks.Cells(r, 5) = wks.Cells(r - 1, 5) _
And wks.Cells(r, 6) = wks.Cells(r - 1, 6) _
And wks.Cells(r, 7) = wks.Cells(r - 1, 7) Then
' Update Start Date on Previous Row
If CDate(wks.Cells(r, 8)) < CDate(wks.Cells(r - 1, 8)) Then
wks.Cells(r - 1, 8) = wks.Cells(r, 8)
End If
' Update End Date on Previous Row
If CDate(wks.Cells(r, 9)) > CDate(wks.Cells(r - 1, 9)) Then
wks.Cells(r - 1, 9) = wks.Cells(r, 9)
End If
' Delete Duplicate
Rows(r).Delete
End If
Next
End Sub
Related
I hope you can help. I have a piece of code and it works relatively well.
What it does is it allows a user to click on a command button which opens up a dialog box. The user then selects another excel sheet, then the code identifies duplicates consolidates these duplicates creating a new row of data with the earliest available start date and latest available end date and then deletes the duplicates
So in Pic 1 you can see the selected sheet has duplicate entries and multiple start and end dates for these duplicate entries
Pic 1
Pic 2 shows the sheet after the code has executed
You can see in Pic 2 that the duplicates have been consolidated and a row of data with the earliest start date and latest end date is left
Agnholt Jørgen Steen is correct
Andersen Anders Nyboe is correct
But it only works if the duplicates are directly under eachother if they are not as in the case with
Christensen Tove and Christensen Trine Tang my code is unable to identify the duplicates and it does not consolidate or work the dates.
Can my code be amended to fix this issue of duplicates not being directly underneath each other?
My code is below as always and all help is greatly appreciated.
MY CODE
Sub Open_Workbook_Dialog()
Dim strFileName As String
Dim wkb As Workbook
Dim wks As Worksheet
Dim lastRow As Long
Dim r As Long
MsgBox "Select Denmark File" '<--| txt box for prompt to pick a file
strFileName = Application.GetOpenFilename(FileFilter:="Excel Files,*.xl*;*.xm*") '<--| Opens the file window to allow selection
Set wkb = Application.Workbooks.Open(strFileName)
Set wks = ActiveWorkbook.Sheets(1)
lastRow = wks.UsedRange.Rows.Count
For r = lastRow To 3 Step -1
' Identify Duplicate
If wks.Cells(r, 1) = wks.Cells(r - 1, 1) _
And wks.Cells(r, 2) = wks.Cells(r - 1, 2) _
And wks.Cells(r, 3) = wks.Cells(r - 1, 3) _
And wks.Cells(r, 4) = wks.Cells(r - 1, 4) _
And wks.Cells(r, 5) = wks.Cells(r - 1, 5) _
And wks.Cells(r, 6) = wks.Cells(r - 1, 6) _
And wks.Cells(r, 7) = wks.Cells(r - 1, 7) Then
' Update Start Date on Previous Row
If CDate(wks.Cells(r, 8)) < CDate(wks.Cells(r - 1, 8)) Then
wks.Cells(r - 1, 8) = wks.Cells(r, 8)
End If
' Update End Date on Previous Row
If CDate(wks.Cells(r, 9)) > CDate(wks.Cells(r - 1, 9)) Then
wks.Cells(r - 1, 9) = wks.Cells(r, 9)
End If
' Delete Duplicate
Rows(r).Delete
End If
Next
End Sub
So i have amended the code to sort Column B but it still leave duplicates
my Code with the sort added is below again any help is greatly appreciated.
CODE
Sub Open_Workbook_Dialog()
Dim strFileName As String
Dim wkb As Workbook
Dim wks As Worksheet
Dim lastRow As Long
Dim r As Long
MsgBox "Select Denmark File" '<--| txt box for prompt to pick a file
strFileName = Application.GetOpenFilename(FileFilter:="Excel Files,*.xl*;*.xm*") '<--| Opens the file window to allow selection
Set wkb = Application.Workbooks.Open(strFileName)
Set wks = ActiveWorkbook.Sheets(1)
lastRow = wks.UsedRange.Rows.Count
With ActiveWorkbook.Sheets(1)
.Unprotect
lastcol = .Cells(1, .Columns.Count).End(xlToLeft).Column
.Range("A1").Resize(79, lastcol).Sort Key1:=Range("B1"), _
Order1:=xlAscending, _
Header:=xlGuess, _
OrderCustom:=1, _
MatchCase:=False, _
Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
End With
For r = lastRow To 3 Step -1
' Identify Duplicate
If wks.Cells(r, 1) = wks.Cells(r - 1, 1) _
And wks.Cells(r, 2) = wks.Cells(r - 1, 2) _
And wks.Cells(r, 3) = wks.Cells(r - 1, 3) _
And wks.Cells(r, 4) = wks.Cells(r - 1, 4) _
And wks.Cells(r, 5) = wks.Cells(r - 1, 5) _
And wks.Cells(r, 6) = wks.Cells(r - 1, 6) _
And wks.Cells(r, 7) = wks.Cells(r - 1, 7) Then
' Update Start Date on Previous Row
If CDate(wks.Cells(r, 8)) < CDate(wks.Cells(r - 1, 8)) Then
wks.Cells(r - 1, 8) = wks.Cells(r, 8)
End If
' Update End Date on Previous Row
If CDate(wks.Cells(r, 9)) > CDate(wks.Cells(r - 1, 9)) Then
wks.Cells(r - 1, 9) = wks.Cells(r, 9)
End If
' Delete Duplicate
Rows(r).Delete
End If
Next
End Sub
Your code removes duplicates that are one after another. Those duplicates don't touch, thus aren't deleted.
This way of doing is faster (linear and not quadratic like normal duplicate finding code) but does not work if some duplicates don't touch)
Solution : You should sort the table (with regard to all columns, not just the first one) before running the code. This way duplicates will always touch.
I hope you can help. I have a piece of code and it works relatively well.
What it does is it opens up a dialog box using a command button that allows a user to select another excel sheet once this sheet is selected the code then consolidates the duplicates and creates a new row with the earliest possible start date and latest possible end date then deletes the duplicate rows.
So in Pic 1
We can see that we have duplicate rows with multiple start date and end dates what the code should do is find the duplicates with the earliest start date and latest end date and make a new line.
Pic 1.
In Pic 2
you can see that the duplicates have been removed and for the first duplicate the dates are correct with the earliest start date and latest end date possible available Agnholt Jørgen Steen Start date 01/04/2016 end date 17/06/2016
But for Breum Leif its the wrong way round 04/05/2016 13/01/2016
Pic 2.
Can my code be amended to solve this issue. As always any help is greatly appreciated.
My code is below.
CODE
Sub Open_Workbook_Dialog()
Dim strFileName As String
Dim wkb As Workbook
Dim wks As Worksheet
Dim lastRow As Long
Dim r As Long
MsgBox "Select Denmark File" '<--| txt box for prompt to pick a file
strFileName = Application.GetOpenFilename(FileFilter:="Excel Files,*.xl*;*.xm*") '<--| Opens the file window to allow selection
Set wkb = Application.Workbooks.Open(strFileName)
Set wks = ActiveWorkbook.Sheets(1)
lastRow = wks.UsedRange.Rows.Count
For r = lastRow To 3 Step -1
' Identify Duplicate
If wks.Cells(r, 1) = wks.Cells(r - 1, 1) _
And wks.Cells(r, 2) = wks.Cells(r - 1, 2) _
And wks.Cells(r, 3) = wks.Cells(r - 1, 3) _
And wks.Cells(r, 4) = wks.Cells(r - 1, 4) _
And wks.Cells(r, 5) = wks.Cells(r - 1, 5) _
And wks.Cells(r, 6) = wks.Cells(r - 1, 6) _
And wks.Cells(r, 7) = wks.Cells(r - 1, 7) Then
' Update Start Date on Previous Row
If wks.Cells(r, 8) < wks.Cells(r - 1, 8) Then
wks.Cells(r - 1, 8) = wks.Cells(r, 8)
End If
' Update End Date on Previous Row
If wks.Cells(r, 9) > wks.Cells(r - 1, 9) Then
wks.Cells(r - 1, 9) = wks.Cells(r, 9)
End If
' Delete Duplicate
Rows(r).Delete
End If
Next
End Sub
Judging by your output, it appears that the cells in column H and I are text, not dates. Thus "04/05/2016" is less than "13/01/2016", and (for Anders Nyboe Andersen) "15/03/2016" is greater than "14/03/2016" is greater than "07/04/2016".
Providing your locale settings are such that dates are represented as "dd/mm/yyyy" format (your profile says Ireland, so I am guessing that they are), you can get your tests working by converting the text in the cells to be a Date prior to performing your comparisons:
' Update Start Date on Previous Row
If CDate(wks.Cells(r, 8)) < CDate(wks.Cells(r - 1, 8)) Then
wks.Cells(r - 1, 8) = wks.Cells(r, 8)
End If
' Update End Date on Previous Row
If CDate(wks.Cells(r, 9)) > CDate(wks.Cells(r - 1, 9)) Then
wks.Cells(r - 1, 9) = wks.Cells(r, 9)
End If
I'm trying to run a For Next Loop until the last row of a specific column (but not the last row of the sheet). So the first part of my list has data in column F and the second part doesn't. I only want the macro to apply to that first part. For some reason the loop only runs through the first part with certain commands but doesn't with the ones I am trying to do now. (I know it would be easy just to seperate the two parts manually and then run it but it drives me nuts not knowing what it is I did wrong :)).
This is the code:
Dim i As Integer
Dim g As Double
g = 0.083333333
Dim lastrow As Long
lastrow = Sheets("zm").Range("f" & Rows.Count).End(xlUp).Row
Sheets("zm").Activate
For i = 2 To lastrow
If Sheets("zm").Cells(i, 1) = Sheets("zm").Cells(i + 1, 1) And Sheets("zm").Cells(i, 5) = Sheets("zm").Cells(i + 1, 5) And Sheets("zm").Cells(i + 1, 6) - Sheets("zm").Cells(i, 7) < g Then
Sheets("zm").Cells(i + 1, 7).Copy
Sheets("zm").Cells(i, 7).Select
ActiveSheet.Paste
Application.CutCopyMode = False
Sheets("zm").Rows(i + 1).Delete
End If
Next i
Thanks for your help!
avoid Select/Selection and/or Activate/ActiveXXX
try this:
Option Explicit
Sub main()
Dim i As Long, lastrow As Long
Dim g As Double
g = 0.083333333
With Worksheets("zm")
lastrow = .Cells(.Rows.Count, "F").End(xlUp).Row
For i = lastrow To 2 Step -1
If .Cells(i, 1) = .Cells(i + 1, 1) And .Cells(i, 5) = .Cells(i + 1, 5) And .Cells(i + 1, 6) - .Cells(i, 7) < g Then
.Cells(i + 1, 7).Copy Destination:=.Cells(i, 7)
.Rows(i + 1).Delete
End If
Next i
End With
End Sub
I received many Excel files from a client.
Their system extracted the data into a spreadsheet, but one column is having issues. If the text was too long, it would put the remaining text into the cell below it.
This causes all the other fields in that row to be blank, except for the overflow.
How can I merge cells at issue into one for all files I received?
I uploaded a screen shot of the file as an example. Notice on row 8 that H8 is the only cell. That needs to be merged with H7. Not every row is at issue though.
asuming A is the main (and empty for doubles)
asuming H holds the text
then in L1 and copy down
=H1&IF(LEN(A2),H2,"")
simplest way (then copy values from L to H and delete empty lines (simply with filter)
when having unknown number of lines (after splitting) you better use vba (or simply repeat the whole procedure till there no empty lines anymore...
doing it in VBA:
Sub testing()
Dim i As Long
While Len(Cells(i + 1, 8))
i = i + 1
While Len(Cells(i + 1, 1)) = 0 And Len(Cells(i + 1, 8))
Cells(i, 8) = Cells(i, 8) & Cells(i + 1, 8)
Rows(i + 1).Delete
Wend
Wend
End Sub
most programs skip spaces so you may want to use:
=H1&IF(LEN(A2)," "&H2,"")
or for vba change Cells(i, 8) = Cells(i, 8) & Cells(i + 1, 8) to Cells(i, 8) = Cells(i, 8) & " " & Cells(i + 1, 8)
This will concatenate the texts in H and delete the row that is not useful :
Sub test_bm11()
Dim wS As Worksheet, _
LastRow As Long, _
i As Long
Set wS = ActiveSheet
With wS
LastRow = .Range("H" & .Rows.Count).End(xlUp).Row
For i = LastRow To 2 Step -1
If .Cells(i, "A") <> vbNullString Then
Else
.Cells(i, "H").Offset(-1, 0) = .Cells(i, "H").Offset(-1, 0) & .Cells(i, "H")
.Cells(i, "H").EntireRow.Delete
End If
Next i
End With
End Sub
I cannot seem to solve this VBA riddle I've been working on, please help. I'm new at this and I'm probably over complicating it
Essentially, there are two worksheets - one titled Master and the other will be created fresh daily by date. The Master tab contains 10000 rows of historical data filled from Columns A:X. The other tab generally has about 300 rows of fresh data and also contains like Columns A:X, only with blank cells in Columns A:B. I'm trying to find matches with the master tab, and if so, populate the corresponding results in cells A and B from the master to the daily. If nothing, leave blank. It is crucial that Cells H:M and R:W are identical matches.
Below is my crazy attempt, Thank you in advance for helping
Sub Previous()
Dim u As Long
u = 2
Do While ActiveSheet.Cells(u, 6) <> ""
Dim i As Long
i = 2
Do While Worksheets("Master").Cells(i, 6) <> ""
If ActiveSheet.Range(Cells(u, 8), Cells(u, 13)) _
= Worksheets("Master").Range(Cells(i, 8), Cells(i, 13)) _
And ActiveSheet.Range(Cells(u, 18), Cells(u, 23)) _
= Worksheets("Master").Range(Cells(i, 18), Cells(i, 23)) _
And ActiveSheet.Cells(u, 2) = "" Then
ActiveSheet.Range(Cells(u, 1), Cells(u, 2)) _
= Worksheets("Master").Range(Cells(i, 1), Cells(i, 2))
Else: i = i + 1
End If
Loop
u = u + 1
i = 2
Loop
End Sub
First of all, I don't believe this snippet does what you think it does.
Worksheets("Master").Range(Cells(i, 8), Cells(i, 13))
In that snippet Cells(i,8) references the ActiveSheet, not Sheets("Master").
There is a note on this about halfway down the page on msdn's Range Object documentation.
You can simplify your code a great deal by assigning some worksheet variables.
dim actWs as Worksheet
dim mstWs as Worksheet
Set actWs = Activesheet
Set mstWs = Sheets("Master")
'then reference your ranges like this
mstWs.Cells(i,8)
But, that's not what is causing your runtime error.
Simply put, you can not compare ranges that way. You need to check the value of each cell, so you end up with another layer of nested loops.
dim u as long ' active sheet row counter
dim i as long ' master sheet row counter
dim c as long ' column counter
For u = 2 to actWs.Range("A" & .Rows.Count).End(xlUp).Row 'find last row in column "A" of active sheet
For i = 2 to mstWs.Range("A" & .Rows.Count).End(xlUp).Row 'find last row in column "A" of master sheet
For c = 8 to 13
If actWs.Cells(i,c) = mstWs.Cells(i,c) Then
'Do stuff
End if
next c 'next column
next i 'next master sheet row
next u 'next active sheet row
This is obviously a simplified version of what you'll need to do. Be careful of line continuations (" _ ") and code indentation. It's easy to trick yourself into thinking your program should flow in a way that it isn't. It would be advisable to store the value's you're checking for equality in variables to make it easier to read. You might more readily notice where you're going wrong.
Sub Previous()
Dim actWs As Worksheet
Set actWs = ActiveSheet
Dim mstWs As Worksheet
Set mstWs = Sheets("Master")
Dim u As Long
Dim i As Long
u = 2
Do While actWs.Cells(u, 6) <> ""
For i = 2 To mstWs.Range("C" & Rows.Count).End(xlUp).Row
If actWs.Cells(u, 8) = mstWs.Cells(i, 8) And actWs.Cells(u, 9) = mstWs.Cells(i, 9) And actWs.Cells(u, 10) = mstWs.Cells(i, 10) And actWs.Cells(u, 11) = mstWs.Cells(i, 11) And actWs.Cells(u, 12) = mstWs.Cells(i, 12) And actWs.Cells(u, 13) = mstWs.Cells(i, 13) And actWs.Cells(u, 18) = mstWs.Cells(i, 18) And actWs.Cells(u, 19) = mstWs.Cells(i, 19) And actWs.Cells(u, 20) = mstWs.Cells(i, 20) And actWs.Cells(u, 21) = mstWs.Cells(i, 21) And actWs.Cells(u, 22) = mstWs.Cells(i, 22) And actWs.Cells(u, 23) = mstWs.Cells(i, 23) Then
mstWs.Select
Range(Cells(i, 1), Cells(i, 2)).Select
Selection.Copy
actWs.Select
Range(Cells(u, 1), Cells(u, 2)).Select
actWs.Paste
End If
Next i
u = u + 1
Loop
End Sub