Automatically remove duplicate data when pasting into excel - excel

I have a set of CSV data copied from a grid in third party program that I want to paste into excel. The data consists of names in the first column and dates/times in the second column. The data is descending order of time and continually updated. The problem is that the grid for whatever reason has a limit of 1000 rows and as it belongs to s third party app, I can’t get the limit increased.
I want to be able to automatically remove duplicate rows based on the name column in the data set and keep the row with the oldest time.
The trickier bit is that I will be continually adding to the excel grid so I need to also check against the existing data in excel and remove any duplicate rows from the data to be pasted.
I want to be able to do this automatically as I will not have enough time to quickly format it manually.
So is there a way to achieve this?
Thanks,
iq

Put this code into the worksheet's private code sheet.
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Count > 1 Then
On Error GoTo meh
Application.EnableEvents = False
With Cells(1, 1).CurrentRegion
.Cells.Sort Key1:=.Columns(2), Order1:=xlAscending, _
Orientation:=xlTopToBottom, Header:=xlYes
.Cells.RemoveDuplicates Columns:=1, Header:=xlYes
End With
End If
meh:
Application.EnableEvents = True
End Sub
This is triggered by 2 or more cells of data being pasted into the worksheet.

Related

Conditionally copy, paste, delete between worksheets data missing

I have inherited a workbook that has suffered months of abuse (poor data entry, poor cut and paste, duplications, etc). I have nearly finished sorting the data but to prevent similar problems I am trying to automate some of the process. I am new to VBA and cannot figure out why my code isn't working. There are several worksheets that track an application through our new client process. Each worksheet has the same fifteen columns, metadata in the first 10 rows (=sum counts) and headers in the 11th row. When we receive interest in joining our organisation some simple data is entered into columns A-D and L-O inclusive. I want a particular row to move to the next worksheet when a date is entered to indicate a step in the process has been completed. For example when a client returns an application form, the date is entered into column G and the specific row is moved to the next worksheet and deleted from the original. The date entry works but columns L-O are not being copied. HELP!
The code I'm using is:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("G12:G100" & Range("A" & Rows.Count).End(xlUp).Row)) Is Nothing And Target.Cells.Count = 1 Then
If IsDate(Target.Value) = True Then
Range(Cells(Target.Row, "A"), Target).Copy Sheets("Awaiting Interview").Range("A" & Rows.Count).End(xlUp).Offset(1, 0)
Target.EntireRow.Delete
End If
End If
End Sub
Thank in advance.
AlVBA

Excel 2017. 7 worksheets, 1 filter to change them all

I have 7 worksheets which do exactly what I want. I am now being asked for a filter to show specific years. Done. However to look at a year of trend data, I have to manually filter each sheet.
I wouldn't mind going the extra mile, and if it's possible, have a filter in one of these sheets that organises the year in all the other sheets.
I have=YEAR(O9:O29148) on my largest sheet. A8:O8 and everything above is exactly the same on each sheet, every sheet has the same type of data in the same column. The only thing that does change is the unique data itself.
What I want is to have a Year filter (2000-2018) on my dashboard, which will then filter all the worksheets to show the same year, or all data if required.
Is this even possible?
(I do not understand VBA code, but I am capable of inserting it into VBA editor and then running said macro).
Any help would be greatly appreciated, thank you!
Not really knowing a lot about the way your data is set up, I build the following, with this code on the worksheet_change event of the dashboard sheet, where I have E6 controlling the year. I have 3 other sheets with data in column A with year numbers, you can use this as a base. You will need to experiment with your column, on the filter, number most likely.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim wsWorksheet As Excel.Worksheet
If Target.Cells(1, 1).Address(False, False) = "E6" and Target.Cells.Count=1 Then
For Each wsWorksheet In ThisWorkbook.Worksheets
With wsWorksheet
If .Name <> Target.Worksheet.Name Then
If .UsedRange.AutoFilter Then
.UsedRange.AutoFilter 1, Target.Value
End If
End If
End With
Next wsWorksheet
End If
End Sub
Public Sub Filter_Sheets()
Dim i As Long
Dim comboBox As ControlFormat
With ThisWorkbook
Set comboBox = .Worksheets(9).Shapes("Drop Down 229").ControlFormat
For i = 1 To Worksheets.Count
.Worksheets(i).UsedRange.AutoFilter Field:=15, Criteria1:=comboBox.List(comboBox.ListIndex)
Next
End With
End Sub
This is the best fit I have managed to discover. I still get an error (AutoFilter method of Range class failed). However this does work. I am now using a combobox to change the auto filter on all 7 sheets as needed. In order to go back to select all, having "<>" in a cell the dropdown references, works to select all the data again.

Automatically updating two Excel sheets

I have two Excel sheets with the same columns, and I want a way by which if I update rows in one table, the corresponding rows in other tables are automatically also updated, and vice versa for both the tables?
Does a way like this exist? I searched a lot, but could not find the vice versa option.
You'll need to use some VBA to do this. Something like the following will work, which needs to be embedded in the script window for each sheet that contains your data. This assumes your data is in the same location on each sheet i.e. A1:A10.
Private Sub Worksheet_Change(ByVal Target As Range)
'First Column
Set KeyCells = Worksheets("sheet 1").Range("A1:A10")
'Only undertake action if key cells are edited
If Not Application.Intersect(KeyCells, Range(Target.Address)) _
Is Nothing Then
'Edit second column
Worksheets("sheet 2").Range(Target.Address) = Target.Value
End If
End Sub
You'll obviously need to duplicate this to work for changes to sheet 2 and also and embedded the code in sheet 2.

How to select clear table contents without destroying the table?

I have a vba function in excel 2010 that I built using help from people on here. This function copies the contents of a table/form, sorts them, and sends them to the appropriate tables.
Now after running this function I want the original table to be cleared. I can achieve this with the following code, assuming ACell has been defined as the first cell in the table.
ACell.ListObject.Range.ClearContents works fine, the only problem is it deletes the table as well as the data values.
Is there any way around this? I would rather not have to set the table up every time I enter some data.
How about:
ACell.ListObject.DataBodyRange.Rows.Delete
That will keep your table structure and headings, but clear all the data and rows.
EDIT: I'm going to just modify a section of my answer from your previous post, as it does mostly what you want. This leaves just one row:
With loSource
.Range.AutoFilter
.DataBodyRange.Offset(1).Resize(.DataBodyRange.Rows.Count - 1, .DataBodyRange.Columns.Count).Rows.Delete
.DataBodyRange.Rows(1).Specialcells(xlCellTypeConstants).ClearContents
End With
If you want to leave all the rows intact with their formulas and whatnot, just do:
With loSource
.Range.AutoFilter
.DataBodyRange.Specialcells(xlCellTypeConstants).ClearContents
End With
Which is close to what #Readify suggested, except it won't clear formulas.
Try just clearing the data (not the entire table including headers):
ACell.ListObject.DataBodyRange.ClearContents
I reworked Doug Glancy's solution to avoid rows deletion, which can lead to #Ref issue in formulae.
Sub ListReset(lst As ListObject)
'clears a listObject while leaving row 1 empty, with formulae
With lst
If .ShowAutoFilter Then .AutoFilter.ShowAllData
On Error Resume Next
With .DataBodyRange
.Offset(1).Rows.Clear
.Rows(1).SpecialCells(xlCellTypeConstants).ClearContents
End With
On Error GoTo 0
.Resize .Range.Rows("1:2")
End With
End Sub
There is a condition that most of these solutions do not address. I revised Patrick Honorez's solution to handle it. I felt I had to share this because I was pulling my hair out when the original function was occasionally clearing more data that I expected.
The situation happens when the table only has one column and the .SpecialCells(xlCellTypeConstants).ClearContents attempts to clear the contents of the top row. In this situation, only one cell is selected (the top row of the table that only has one column) and the SpecialCells command applies to the entire sheet instead of the selected range. What was happening to me was other cells on the sheet that were outside of my table were also getting cleared.
I did some digging and found this advice from Mathieu Guindon:
Range SpecialCells ClearContents clears whole sheet
Range({any single cell}).SpecialCells({whatever}) seems to work off the entire sheet.
Range({more than one cell}).SpecialCells({whatever}) seems to work off the specified cells.
If the list/table only has one column (in row 1), this revision will check to see if the cell has a formula and if not, it will only clear the contents of that one cell.
Public Sub ClearList(lst As ListObject)
'Clears a listObject while leaving 1 empty row + formula
' https://stackoverflow.com/a/53856079/1898524
'
'With special help from this post to handle a single column table.
' Range({any single cell}).SpecialCells({whatever}) seems to work off the entire sheet.
' Range({more than one cell}).SpecialCells({whatever}) seems to work off the specified cells.
' https://stackoverflow.com/questions/40537537/range-specialcells-clearcontents-clears-whole-sheet-instead
On Error Resume Next
With lst
'.Range.Worksheet.Activate ' Enable this if you are debugging
If .ShowAutoFilter Then .AutoFilter.ShowAllData
If .DataBodyRange.Rows.Count = 1 Then Exit Sub ' Table is already clear
.DataBodyRange.Offset(1).Rows.Clear
If .DataBodyRange.Columns.Count > 1 Then ' Check to see if SpecialCells is going to evaluate just one cell.
.DataBodyRange.Rows(1).SpecialCells(xlCellTypeConstants).ClearContents
ElseIf Not .Range.HasFormula Then
' Only one cell in range and it does not contain a formula.
.DataBodyRange.Rows(1).ClearContents
End If
.Resize .Range.Rows("1:2")
.HeaderRowRange.Offset(1).Select
' Reset used range on the sheet
Dim X
X = .Range.Worksheet.UsedRange.Rows.Count 'see J-Walkenbach tip 73
End With
End Sub
A final step I included is a tip that is attributed to John Walkenbach, sometimes noted as J-Walkenbach tip 73 Automatically Resetting The Last Cell
I use this code to remove my data but leave the formulas in the top row. It also removes all rows except for the top row and scrolls the page up to the top.
Sub CleanTheTable()
Application.ScreenUpdating = False
Sheets("Data").Select
ActiveSheet.ListObjects("TestTable").HeaderRowRange.Select
'Remove the filters if one exists.
If ActiveSheet.FilterMode Then
Selection.AutoFilter
End If
'Clear all lines but the first one in the table leaving formulas for the next go round.
With Worksheets("Data").ListObjects("TestTable")
.Range.AutoFilter
On Error Resume Next
.DataBodyRange.Offset(1).Resize(.DataBodyRange.Rows.Count - 1, .DataBodyRange.Columns.Count).Rows.Delete
.DataBodyRange.Rows(1).SpecialCells(xlCellTypeConstants).ClearContents
ActiveWindow.SmallScroll Down:=-10000
End With
Application.ScreenUpdating = True
End Sub
I usually use something very simple if you just want to clear table contents.
Sub Clear_table()
Range("Table1").ClearContents
End Sub
Obviously if you have a workbook with multiple pages you might want to change the code to accommodate that.
Sub Clear_table()
Worksheets("Sheet1").Range("Table1").ClearContents
End Sub
If you want to delete the entire table except your headers, and your formula, you can try this:
Sub DeteteTableExceptFormula()
Dim tb As ListObject
Set tb = activeworksheet.ListObjects("MyTable")
tb.DataBodyRange.Delete
End Sub

Moving Rows to another sheet in a workbook

I need Help!
I am not well versed in VBA or Macros but i cannot find any other way to accomplish what i need to do without using it.
I have a sheet which i will be using to track Purchase orders, and what i need to do is; when i have a row in sheet 1 (Purchase Orders) which has been recieved i.e. the date of receipt has been recorded in column H i need for the entire row to be cut and pasted into sheet 2 (Received orders).
The header takes up the first 7 rows the rows, so i need the macro to look at rows 8-54. Once the received items are removed from sheet 1, i need the row to also be deleted or preferably for the list to be sorted by column A moving the now empty row which has been cut from open for a future entry.
Any help would be greatly appreciated.
The "Record Macro" feature should be enough to do the task you describe.. In Excel 2007, go to the Developer tab in the Ribbon, and select "Record Macro", and perform exactly the steps you are describing. It will record the equivalent VBA code, which you can then execute - or tweak/modify.
I tested this out, here's one way to do it:
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
Dim receivedDate As Range, nextOpen As Range, isect As Range
Set receivedDate = Sheet1.Range("H8:H54")
Set isect = Application.Intersect(Target, receivedDate)
If Not (isect Is Nothing) And IsDate(Target) = True Then
Set nextOpen = Sheet2.Range("A1").End(xlDown).Offset(1, 0)
Target.EntireRow.Copy Destination:=nextOpen.EntireRow
Target.EntireRow.Delete
End If
Application.EnableEvents = True
End Sub
This would be pasted into the Sheet1 code. Any time a cell is changed on sheet1, the code checks to see if it's in the critical range that you specified. (H8:H54) If it is, it then checks to see if it's a date. If it is, it then copies the entire row, puts it in the next open row on Sheet2, and deletes the original row. The cells below it will get shifted up so there are no gaps.
Since the code functions on a cell changing event, it disables "Application.EnableEvents" in order to avoid a loop of changing a cell to call an event which changes a cell to call an event... etc.

Resources