Home |
Search |
Today's Posts |
#1
![]()
Posted to microsoft.public.excel.programming
|
|||
|
|||
![]()
I have a code from Ron de Bruin's website that I used to copy rows from a
data sheet to multiple other sheets based on the contents of a cell in column AG. The code worked great in setting up the sheets. The problem I get is when I add a row to the data sheet and run the code I get an error message, "Subscript out of range". The data sheet has 33 colums ending in AG. I do not have any merged cells, there are no empty rows and the headers are unique. I need to be able to add a row to the data sheet and have it copied to the corresponding sheet. Here is a copy of the code I am using: Sub Copy_To_Worksheets_2() ' This sub uses the functions LastRow and SheetExists Dim CalcMode As Long Dim ws1 As Worksheet Dim ws2 As Worksheet Dim WSNew As Worksheet Dim rng As Range Dim cell As Range Dim Lrow As Long Dim DestRange As Range Dim FieldNum As Integer Dim Lr As Long 'Name of the sheet with your data Set ws1 = Sheets("All") '<<< Change 'Set filter range : A1 is the top left cell of your filter range and 'the header of the first column, D is the last column in the filter range Set rng = ws1.Range("A1:ag" & Rows.Count) 'Set Field number of the filter column 'This example filters on the first field in the range(change the field if needed) 'In this case the range starts in A so Field:=1 is column A, 2 = column B, ...... FieldNum = 33 With Application CalcMode = .Calculation .Calculation = xlCalculationManual .ScreenUpdating = False End With ' Add a worksheet to copy the a unique list and add the CriteriaRange Set ws2 = Worksheets.Add With ws2 'first we copy the Unique data from the filter field to ws2 rng.Columns(FieldNum).AdvancedFilter _ Action:=xlFilterCopy, _ CopyToRange:=.Range("A1"), Unique:=True 'loop through the unique list in ws2 and filter/copy to a worksheet Lrow = .Cells(Rows.Count, "A").End(xlUp).Row For Each cell In .Range("A2:A" & Lrow) If SheetExists(cell.Value) = False Then Set WSNew = Sheets.Add On Error Resume Next WSNew.Name = cell.Value If Err.Number 0 Then MsgBox "Change the name of : " & WSNew.Name & " manually" Err.Clear End If On Error GoTo 0 Set DestRange = WSNew.Range("A1") Else Set WSNew = Sheets(cell.Text) Lr = LastRow(WSNew) Set DestRange = WSNew.Range("A" & Lr + 1) End If 'Firstly, remove the AutoFilter ws1.AutoFilterMode = False 'Filter the range rng.AutoFilter Field:=FieldNum, Criteria1:="=" & cell.Value 'Copy the visible data and use PasteSpecial to paste to the worksheet ws1.AutoFilter.Range.Copy With DestRange .Parent.Select ' Paste:=8 will copy the columnwidth in Excel 2000 and higher .PasteSpecial Paste:=8 .PasteSpecial xlPasteValues .PasteSpecial xlPasteFormats Application.CutCopyMode = False .Select End With ' Delete the header row if you copy to a existing worksheet If Lr 0 Then WSNew.Range("A" & Lr + 1).EntireRow.Delete 'Close AutoFilter ws1.AutoFilterMode = False Lr = 0 Next cell 'Delete the ws2 sheet On Error Resume Next Application.DisplayAlerts = False .Delete Application.DisplayAlerts = True On Error GoTo 0 End With With Application .ScreenUpdating = True .Calculation = CalcMode End With End Sub |
#2
![]()
Posted to microsoft.public.excel.programming
|
|||
|
|||
![]()
Which line causes the error?
The "Subscript out of range" can mean something as simple as a worksheet that doesn't exist: worksheets("doesnotexist").range("a1").value = 5 Homer wrote: I have a code from Ron de Bruin's website that I used to copy rows from a data sheet to multiple other sheets based on the contents of a cell in column AG. The code worked great in setting up the sheets. The problem I get is when I add a row to the data sheet and run the code I get an error message, "Subscript out of range". The data sheet has 33 colums ending in AG. I do not have any merged cells, there are no empty rows and the headers are unique. I need to be able to add a row to the data sheet and have it copied to the corresponding sheet. Here is a copy of the code I am using: Sub Copy_To_Worksheets_2() ' This sub uses the functions LastRow and SheetExists Dim CalcMode As Long Dim ws1 As Worksheet Dim ws2 As Worksheet Dim WSNew As Worksheet Dim rng As Range Dim cell As Range Dim Lrow As Long Dim DestRange As Range Dim FieldNum As Integer Dim Lr As Long 'Name of the sheet with your data Set ws1 = Sheets("All") '<<< Change 'Set filter range : A1 is the top left cell of your filter range and 'the header of the first column, D is the last column in the filter range Set rng = ws1.Range("A1:ag" & Rows.Count) 'Set Field number of the filter column 'This example filters on the first field in the range(change the field if needed) 'In this case the range starts in A so Field:=1 is column A, 2 = column B, ...... FieldNum = 33 With Application CalcMode = .Calculation .Calculation = xlCalculationManual .ScreenUpdating = False End With ' Add a worksheet to copy the a unique list and add the CriteriaRange Set ws2 = Worksheets.Add With ws2 'first we copy the Unique data from the filter field to ws2 rng.Columns(FieldNum).AdvancedFilter _ Action:=xlFilterCopy, _ CopyToRange:=.Range("A1"), Unique:=True 'loop through the unique list in ws2 and filter/copy to a worksheet Lrow = .Cells(Rows.Count, "A").End(xlUp).Row For Each cell In .Range("A2:A" & Lrow) If SheetExists(cell.Value) = False Then Set WSNew = Sheets.Add On Error Resume Next WSNew.Name = cell.Value If Err.Number 0 Then MsgBox "Change the name of : " & WSNew.Name & " manually" Err.Clear End If On Error GoTo 0 Set DestRange = WSNew.Range("A1") Else Set WSNew = Sheets(cell.Text) Lr = LastRow(WSNew) Set DestRange = WSNew.Range("A" & Lr + 1) End If 'Firstly, remove the AutoFilter ws1.AutoFilterMode = False 'Filter the range rng.AutoFilter Field:=FieldNum, Criteria1:="=" & cell.Value 'Copy the visible data and use PasteSpecial to paste to the worksheet ws1.AutoFilter.Range.Copy With DestRange .Parent.Select ' Paste:=8 will copy the columnwidth in Excel 2000 and higher .PasteSpecial Paste:=8 .PasteSpecial xlPasteValues .PasteSpecial xlPasteFormats Application.CutCopyMode = False .Select End With ' Delete the header row if you copy to a existing worksheet If Lr 0 Then WSNew.Range("A" & Lr + 1).EntireRow.Delete 'Close AutoFilter ws1.AutoFilterMode = False Lr = 0 Next cell 'Delete the ws2 sheet On Error Resume Next Application.DisplayAlerts = False .Delete Application.DisplayAlerts = True On Error GoTo 0 End With With Application .ScreenUpdating = True .Calculation = CalcMode End With End Sub -- Dave Peterson |
#3
![]()
Posted to microsoft.public.excel.programming
|
|||
|
|||
![]()
Dave,
Thank you for your help. I realized the problem was something that I was missing in the way the sheet is set up so I re-created the sheet from scratch and it works, almost. When I run the code it adds all rows again so I end up with duplicate rows. I figure if I can have it delete the rows already in place, like it does the header row, the sheets will be updated correctly. Here is a section of the code that I believe I need to do this in, but can't figure out how: ' Delete the header row if you copy to a existing worksheet If Lr 0 Then WSNew.Range("A" & Lr + 1).EntireRow.Delete Thanks again, Don "Dave Peterson" wrote: Which line causes the error? The "Subscript out of range" can mean something as simple as a worksheet that doesn't exist: worksheets("doesnotexist").range("a1").value = 5 Homer wrote: I have a code from Ron de Bruin's website that I used to copy rows from a data sheet to multiple other sheets based on the contents of a cell in column AG. The code worked great in setting up the sheets. The problem I get is when I add a row to the data sheet and run the code I get an error message, "Subscript out of range". The data sheet has 33 colums ending in AG. I do not have any merged cells, there are no empty rows and the headers are unique. I need to be able to add a row to the data sheet and have it copied to the corresponding sheet. Here is a copy of the code I am using: Sub Copy_To_Worksheets_2() ' This sub uses the functions LastRow and SheetExists Dim CalcMode As Long Dim ws1 As Worksheet Dim ws2 As Worksheet Dim WSNew As Worksheet Dim rng As Range Dim cell As Range Dim Lrow As Long Dim DestRange As Range Dim FieldNum As Integer Dim Lr As Long 'Name of the sheet with your data Set ws1 = Sheets("All") '<<< Change 'Set filter range : A1 is the top left cell of your filter range and 'the header of the first column, D is the last column in the filter range Set rng = ws1.Range("A1:ag" & Rows.Count) 'Set Field number of the filter column 'This example filters on the first field in the range(change the field if needed) 'In this case the range starts in A so Field:=1 is column A, 2 = column B, ...... FieldNum = 33 With Application CalcMode = .Calculation .Calculation = xlCalculationManual .ScreenUpdating = False End With ' Add a worksheet to copy the a unique list and add the CriteriaRange Set ws2 = Worksheets.Add With ws2 'first we copy the Unique data from the filter field to ws2 rng.Columns(FieldNum).AdvancedFilter _ Action:=xlFilterCopy, _ CopyToRange:=.Range("A1"), Unique:=True 'loop through the unique list in ws2 and filter/copy to a worksheet Lrow = .Cells(Rows.Count, "A").End(xlUp).Row For Each cell In .Range("A2:A" & Lrow) If SheetExists(cell.Value) = False Then Set WSNew = Sheets.Add On Error Resume Next WSNew.Name = cell.Value If Err.Number 0 Then MsgBox "Change the name of : " & WSNew.Name & " manually" Err.Clear End If On Error GoTo 0 Set DestRange = WSNew.Range("A1") Else Set WSNew = Sheets(cell.Text) Lr = LastRow(WSNew) Set DestRange = WSNew.Range("A" & Lr + 1) End If 'Firstly, remove the AutoFilter ws1.AutoFilterMode = False 'Filter the range rng.AutoFilter Field:=FieldNum, Criteria1:="=" & cell.Value 'Copy the visible data and use PasteSpecial to paste to the worksheet ws1.AutoFilter.Range.Copy With DestRange .Parent.Select ' Paste:=8 will copy the columnwidth in Excel 2000 and higher .PasteSpecial Paste:=8 .PasteSpecial xlPasteValues .PasteSpecial xlPasteFormats Application.CutCopyMode = False .Select End With ' Delete the header row if you copy to a existing worksheet If Lr 0 Then WSNew.Range("A" & Lr + 1).EntireRow.Delete 'Close AutoFilter ws1.AutoFilterMode = False Lr = 0 Next cell 'Delete the ws2 sheet On Error Resume Next Application.DisplayAlerts = False .Delete Application.DisplayAlerts = True On Error GoTo 0 End With With Application .ScreenUpdating = True .Calculation = CalcMode End With End Sub -- Dave Peterson |
#4
![]()
Posted to microsoft.public.excel.programming
|
|||
|
|||
![]()
I would delete the worksheet and start from scratch each time.
This portion: For Each cell In .Range("A2:A" & Lrow) If SheetExists(cell.Value) = False Then Set WSNew = Sheets.Add On Error Resume Next WSNew.Name = cell.Value If Err.Number 0 Then MsgBox "Change the name of : " & WSNew.Name & " manually" Err.Clear End If On Error GoTo 0 Set DestRange = WSNew.Range("A1") Else Set WSNew = Sheets(cell.Text) Lr = LastRow(WSNew) Set DestRange = WSNew.Range("A" & Lr + 1) End If changes to: For Each cell In .Range("A2:A" & Lrow) on error resume next worksheets(Cell.value).delete on error goto 0 Set WSNew = Sheets.Add On Error Resume Next WSNew.Name = cell.Value If Err.Number 0 Then MsgBox "Change the name of : " & WSNew.Name & " manually" Err.Clear End If On Error GoTo 0 Set DestRange = WSNew.Range("A1") ======= The line you suggested to delete points at the copied|Pasted header from the autofilter range. Nothing to do with duplicated rows. Homer wrote: Dave, Thank you for your help. I realized the problem was something that I was missing in the way the sheet is set up so I re-created the sheet from scratch and it works, almost. When I run the code it adds all rows again so I end up with duplicate rows. I figure if I can have it delete the rows already in place, like it does the header row, the sheets will be updated correctly. Here is a section of the code that I believe I need to do this in, but can't figure out how: ' Delete the header row if you copy to a existing worksheet If Lr 0 Then WSNew.Range("A" & Lr + 1).EntireRow.Delete Thanks again, Don "Dave Peterson" wrote: Which line causes the error? The "Subscript out of range" can mean something as simple as a worksheet that doesn't exist: worksheets("doesnotexist").range("a1").value = 5 Homer wrote: I have a code from Ron de Bruin's website that I used to copy rows from a data sheet to multiple other sheets based on the contents of a cell in column AG. The code worked great in setting up the sheets. The problem I get is when I add a row to the data sheet and run the code I get an error message, "Subscript out of range". The data sheet has 33 colums ending in AG. I do not have any merged cells, there are no empty rows and the headers are unique. I need to be able to add a row to the data sheet and have it copied to the corresponding sheet. Here is a copy of the code I am using: Sub Copy_To_Worksheets_2() ' This sub uses the functions LastRow and SheetExists Dim CalcMode As Long Dim ws1 As Worksheet Dim ws2 As Worksheet Dim WSNew As Worksheet Dim rng As Range Dim cell As Range Dim Lrow As Long Dim DestRange As Range Dim FieldNum As Integer Dim Lr As Long 'Name of the sheet with your data Set ws1 = Sheets("All") '<<< Change 'Set filter range : A1 is the top left cell of your filter range and 'the header of the first column, D is the last column in the filter range Set rng = ws1.Range("A1:ag" & Rows.Count) 'Set Field number of the filter column 'This example filters on the first field in the range(change the field if needed) 'In this case the range starts in A so Field:=1 is column A, 2 = column B, ...... FieldNum = 33 With Application CalcMode = .Calculation .Calculation = xlCalculationManual .ScreenUpdating = False End With ' Add a worksheet to copy the a unique list and add the CriteriaRange Set ws2 = Worksheets.Add With ws2 'first we copy the Unique data from the filter field to ws2 rng.Columns(FieldNum).AdvancedFilter _ Action:=xlFilterCopy, _ CopyToRange:=.Range("A1"), Unique:=True 'loop through the unique list in ws2 and filter/copy to a worksheet Lrow = .Cells(Rows.Count, "A").End(xlUp).Row For Each cell In .Range("A2:A" & Lrow) If SheetExists(cell.Value) = False Then Set WSNew = Sheets.Add On Error Resume Next WSNew.Name = cell.Value If Err.Number 0 Then MsgBox "Change the name of : " & WSNew.Name & " manually" Err.Clear End If On Error GoTo 0 Set DestRange = WSNew.Range("A1") Else Set WSNew = Sheets(cell.Text) Lr = LastRow(WSNew) Set DestRange = WSNew.Range("A" & Lr + 1) End If 'Firstly, remove the AutoFilter ws1.AutoFilterMode = False 'Filter the range rng.AutoFilter Field:=FieldNum, Criteria1:="=" & cell.Value 'Copy the visible data and use PasteSpecial to paste to the worksheet ws1.AutoFilter.Range.Copy With DestRange .Parent.Select ' Paste:=8 will copy the columnwidth in Excel 2000 and higher .PasteSpecial Paste:=8 .PasteSpecial xlPasteValues .PasteSpecial xlPasteFormats Application.CutCopyMode = False .Select End With ' Delete the header row if you copy to a existing worksheet If Lr 0 Then WSNew.Range("A" & Lr + 1).EntireRow.Delete 'Close AutoFilter ws1.AutoFilterMode = False Lr = 0 Next cell 'Delete the ws2 sheet On Error Resume Next Application.DisplayAlerts = False .Delete Application.DisplayAlerts = True On Error GoTo 0 End With With Application .ScreenUpdating = True .Calculation = CalcMode End With End Sub -- Dave Peterson -- Dave Peterson |
#5
![]()
Posted to microsoft.public.excel.programming
|
|||
|
|||
![]()
Dave,
Your change works great. Thank you for your assistance. I had an issue in how it was handling a blank cell in column AG. But I figured out that I shouldn't have a blank cell. Thanks, Don "Dave Peterson" wrote: I would delete the worksheet and start from scratch each time. This portion: For Each cell In .Range("A2:A" & Lrow) If SheetExists(cell.Value) = False Then Set WSNew = Sheets.Add On Error Resume Next WSNew.Name = cell.Value If Err.Number 0 Then MsgBox "Change the name of : " & WSNew.Name & " manually" Err.Clear End If On Error GoTo 0 Set DestRange = WSNew.Range("A1") Else Set WSNew = Sheets(cell.Text) Lr = LastRow(WSNew) Set DestRange = WSNew.Range("A" & Lr + 1) End If changes to: For Each cell In .Range("A2:A" & Lrow) on error resume next worksheets(Cell.value).delete on error goto 0 Set WSNew = Sheets.Add On Error Resume Next WSNew.Name = cell.Value If Err.Number 0 Then MsgBox "Change the name of : " & WSNew.Name & " manually" Err.Clear End If On Error GoTo 0 Set DestRange = WSNew.Range("A1") ======= The line you suggested to delete points at the copied|Pasted header from the autofilter range. Nothing to do with duplicated rows. Homer wrote: Dave, Thank you for your help. I realized the problem was something that I was missing in the way the sheet is set up so I re-created the sheet from scratch and it works, almost. When I run the code it adds all rows again so I end up with duplicate rows. I figure if I can have it delete the rows already in place, like it does the header row, the sheets will be updated correctly. Here is a section of the code that I believe I need to do this in, but can't figure out how: ' Delete the header row if you copy to a existing worksheet If Lr 0 Then WSNew.Range("A" & Lr + 1).EntireRow.Delete Thanks again, Don "Dave Peterson" wrote: Which line causes the error? The "Subscript out of range" can mean something as simple as a worksheet that doesn't exist: worksheets("doesnotexist").range("a1").value = 5 Homer wrote: I have a code from Ron de Bruin's website that I used to copy rows from a data sheet to multiple other sheets based on the contents of a cell in column AG. The code worked great in setting up the sheets. The problem I get is when I add a row to the data sheet and run the code I get an error message, "Subscript out of range". The data sheet has 33 colums ending in AG. I do not have any merged cells, there are no empty rows and the headers are unique. I need to be able to add a row to the data sheet and have it copied to the corresponding sheet. Here is a copy of the code I am using: Sub Copy_To_Worksheets_2() ' This sub uses the functions LastRow and SheetExists Dim CalcMode As Long Dim ws1 As Worksheet Dim ws2 As Worksheet Dim WSNew As Worksheet Dim rng As Range Dim cell As Range Dim Lrow As Long Dim DestRange As Range Dim FieldNum As Integer Dim Lr As Long 'Name of the sheet with your data Set ws1 = Sheets("All") '<<< Change 'Set filter range : A1 is the top left cell of your filter range and 'the header of the first column, D is the last column in the filter range Set rng = ws1.Range("A1:ag" & Rows.Count) 'Set Field number of the filter column 'This example filters on the first field in the range(change the field if needed) 'In this case the range starts in A so Field:=1 is column A, 2 = column B, ...... FieldNum = 33 With Application CalcMode = .Calculation .Calculation = xlCalculationManual .ScreenUpdating = False End With ' Add a worksheet to copy the a unique list and add the CriteriaRange Set ws2 = Worksheets.Add With ws2 'first we copy the Unique data from the filter field to ws2 rng.Columns(FieldNum).AdvancedFilter _ Action:=xlFilterCopy, _ CopyToRange:=.Range("A1"), Unique:=True 'loop through the unique list in ws2 and filter/copy to a worksheet Lrow = .Cells(Rows.Count, "A").End(xlUp).Row For Each cell In .Range("A2:A" & Lrow) If SheetExists(cell.Value) = False Then Set WSNew = Sheets.Add On Error Resume Next WSNew.Name = cell.Value If Err.Number 0 Then MsgBox "Change the name of : " & WSNew.Name & " manually" Err.Clear End If On Error GoTo 0 Set DestRange = WSNew.Range("A1") Else Set WSNew = Sheets(cell.Text) Lr = LastRow(WSNew) Set DestRange = WSNew.Range("A" & Lr + 1) End If 'Firstly, remove the AutoFilter ws1.AutoFilterMode = False 'Filter the range rng.AutoFilter Field:=FieldNum, Criteria1:="=" & cell.Value 'Copy the visible data and use PasteSpecial to paste to the worksheet ws1.AutoFilter.Range.Copy With DestRange .Parent.Select ' Paste:=8 will copy the columnwidth in Excel 2000 and higher .PasteSpecial Paste:=8 .PasteSpecial xlPasteValues .PasteSpecial xlPasteFormats Application.CutCopyMode = False .Select End With ' Delete the header row if you copy to a existing worksheet If Lr 0 Then WSNew.Range("A" & Lr + 1).EntireRow.Delete 'Close AutoFilter ws1.AutoFilterMode = False Lr = 0 Next cell 'Delete the ws2 sheet On Error Resume Next Application.DisplayAlerts = False .Delete Application.DisplayAlerts = True On Error GoTo 0 End With With Application .ScreenUpdating = True .Calculation = CalcMode End With End Sub -- Dave Peterson -- Dave Peterson |
#6
![]()
Posted to microsoft.public.excel.programming
|
|||
|
|||
![]()
One way around it is to look at each cell in the range:
For Each cell In .Range("A2:A" & Lrow) if trim(cell.value) = "" then 'skip it else 'do all the work end if Another way may be to sort the results of the advanced filter. If the cell is really empty, it'll sort to the bottom and it won't be included in: For Each cell In .Range("A2:A" & Lrow) But if the cell looks empty (maybe the result of a formula like =""), then this technique wouldn't work. Homer wrote: Dave, Your change works great. Thank you for your assistance. I had an issue in how it was handling a blank cell in column AG. But I figured out that I shouldn't have a blank cell. Thanks, Don "Dave Peterson" wrote: I would delete the worksheet and start from scratch each time. This portion: For Each cell In .Range("A2:A" & Lrow) If SheetExists(cell.Value) = False Then Set WSNew = Sheets.Add On Error Resume Next WSNew.Name = cell.Value If Err.Number 0 Then MsgBox "Change the name of : " & WSNew.Name & " manually" Err.Clear End If On Error GoTo 0 Set DestRange = WSNew.Range("A1") Else Set WSNew = Sheets(cell.Text) Lr = LastRow(WSNew) Set DestRange = WSNew.Range("A" & Lr + 1) End If changes to: For Each cell In .Range("A2:A" & Lrow) on error resume next worksheets(Cell.value).delete on error goto 0 Set WSNew = Sheets.Add On Error Resume Next WSNew.Name = cell.Value If Err.Number 0 Then MsgBox "Change the name of : " & WSNew.Name & " manually" Err.Clear End If On Error GoTo 0 Set DestRange = WSNew.Range("A1") ======= The line you suggested to delete points at the copied|Pasted header from the autofilter range. Nothing to do with duplicated rows. Homer wrote: Dave, Thank you for your help. I realized the problem was something that I was missing in the way the sheet is set up so I re-created the sheet from scratch and it works, almost. When I run the code it adds all rows again so I end up with duplicate rows. I figure if I can have it delete the rows already in place, like it does the header row, the sheets will be updated correctly. Here is a section of the code that I believe I need to do this in, but can't figure out how: ' Delete the header row if you copy to a existing worksheet If Lr 0 Then WSNew.Range("A" & Lr + 1).EntireRow.Delete Thanks again, Don "Dave Peterson" wrote: Which line causes the error? The "Subscript out of range" can mean something as simple as a worksheet that doesn't exist: worksheets("doesnotexist").range("a1").value = 5 Homer wrote: I have a code from Ron de Bruin's website that I used to copy rows from a data sheet to multiple other sheets based on the contents of a cell in column AG. The code worked great in setting up the sheets. The problem I get is when I add a row to the data sheet and run the code I get an error message, "Subscript out of range". The data sheet has 33 colums ending in AG. I do not have any merged cells, there are no empty rows and the headers are unique. I need to be able to add a row to the data sheet and have it copied to the corresponding sheet. Here is a copy of the code I am using: Sub Copy_To_Worksheets_2() ' This sub uses the functions LastRow and SheetExists Dim CalcMode As Long Dim ws1 As Worksheet Dim ws2 As Worksheet Dim WSNew As Worksheet Dim rng As Range Dim cell As Range Dim Lrow As Long Dim DestRange As Range Dim FieldNum As Integer Dim Lr As Long 'Name of the sheet with your data Set ws1 = Sheets("All") '<<< Change 'Set filter range : A1 is the top left cell of your filter range and 'the header of the first column, D is the last column in the filter range Set rng = ws1.Range("A1:ag" & Rows.Count) 'Set Field number of the filter column 'This example filters on the first field in the range(change the field if needed) 'In this case the range starts in A so Field:=1 is column A, 2 = column B, ...... FieldNum = 33 With Application CalcMode = .Calculation .Calculation = xlCalculationManual .ScreenUpdating = False End With ' Add a worksheet to copy the a unique list and add the CriteriaRange Set ws2 = Worksheets.Add With ws2 'first we copy the Unique data from the filter field to ws2 rng.Columns(FieldNum).AdvancedFilter _ Action:=xlFilterCopy, _ CopyToRange:=.Range("A1"), Unique:=True 'loop through the unique list in ws2 and filter/copy to a worksheet Lrow = .Cells(Rows.Count, "A").End(xlUp).Row For Each cell In .Range("A2:A" & Lrow) If SheetExists(cell.Value) = False Then Set WSNew = Sheets.Add On Error Resume Next WSNew.Name = cell.Value If Err.Number 0 Then MsgBox "Change the name of : " & WSNew.Name & " manually" Err.Clear End If On Error GoTo 0 Set DestRange = WSNew.Range("A1") Else Set WSNew = Sheets(cell.Text) Lr = LastRow(WSNew) Set DestRange = WSNew.Range("A" & Lr + 1) End If 'Firstly, remove the AutoFilter ws1.AutoFilterMode = False 'Filter the range rng.AutoFilter Field:=FieldNum, Criteria1:="=" & cell.Value 'Copy the visible data and use PasteSpecial to paste to the worksheet ws1.AutoFilter.Range.Copy With DestRange .Parent.Select ' Paste:=8 will copy the columnwidth in Excel 2000 and higher .PasteSpecial Paste:=8 .PasteSpecial xlPasteValues .PasteSpecial xlPasteFormats Application.CutCopyMode = False .Select End With ' Delete the header row if you copy to a existing worksheet If Lr 0 Then WSNew.Range("A" & Lr + 1).EntireRow.Delete 'Close AutoFilter ws1.AutoFilterMode = False Lr = 0 Next cell 'Delete the ws2 sheet On Error Resume Next Application.DisplayAlerts = False .Delete Application.DisplayAlerts = True On Error GoTo 0 End With With Application .ScreenUpdating = True .Calculation = CalcMode End With End Sub -- Dave Peterson -- Dave Peterson -- Dave Peterson |
#7
![]()
Posted to microsoft.public.excel.programming
|
|||
|
|||
![]()
Dave,
Without your help I would not have been able to make this work. The time, and high blood pressure, I will save is enormous. Thank you very much. Don "Dave Peterson" wrote: One way around it is to look at each cell in the range: For Each cell In .Range("A2:A" & Lrow) if trim(cell.value) = "" then 'skip it else 'do all the work end if Another way may be to sort the results of the advanced filter. If the cell is really empty, it'll sort to the bottom and it won't be included in: For Each cell In .Range("A2:A" & Lrow) But if the cell looks empty (maybe the result of a formula like =""), then this technique wouldn't work. Homer wrote: Dave, Your change works great. Thank you for your assistance. I had an issue in how it was handling a blank cell in column AG. But I figured out that I shouldn't have a blank cell. Thanks, Don "Dave Peterson" wrote: I would delete the worksheet and start from scratch each time. This portion: For Each cell In .Range("A2:A" & Lrow) If SheetExists(cell.Value) = False Then Set WSNew = Sheets.Add On Error Resume Next WSNew.Name = cell.Value If Err.Number 0 Then MsgBox "Change the name of : " & WSNew.Name & " manually" Err.Clear End If On Error GoTo 0 Set DestRange = WSNew.Range("A1") Else Set WSNew = Sheets(cell.Text) Lr = LastRow(WSNew) Set DestRange = WSNew.Range("A" & Lr + 1) End If changes to: For Each cell In .Range("A2:A" & Lrow) on error resume next worksheets(Cell.value).delete on error goto 0 Set WSNew = Sheets.Add On Error Resume Next WSNew.Name = cell.Value If Err.Number 0 Then MsgBox "Change the name of : " & WSNew.Name & " manually" Err.Clear End If On Error GoTo 0 Set DestRange = WSNew.Range("A1") ======= The line you suggested to delete points at the copied|Pasted header from the autofilter range. Nothing to do with duplicated rows. Homer wrote: Dave, Thank you for your help. I realized the problem was something that I was missing in the way the sheet is set up so I re-created the sheet from scratch and it works, almost. When I run the code it adds all rows again so I end up with duplicate rows. I figure if I can have it delete the rows already in place, like it does the header row, the sheets will be updated correctly. Here is a section of the code that I believe I need to do this in, but can't figure out how: ' Delete the header row if you copy to a existing worksheet If Lr 0 Then WSNew.Range("A" & Lr + 1).EntireRow.Delete Thanks again, Don "Dave Peterson" wrote: Which line causes the error? The "Subscript out of range" can mean something as simple as a worksheet that doesn't exist: worksheets("doesnotexist").range("a1").value = 5 Homer wrote: I have a code from Ron de Bruin's website that I used to copy rows from a data sheet to multiple other sheets based on the contents of a cell in column AG. The code worked great in setting up the sheets. The problem I get is when I add a row to the data sheet and run the code I get an error message, "Subscript out of range". The data sheet has 33 colums ending in AG. I do not have any merged cells, there are no empty rows and the headers are unique. I need to be able to add a row to the data sheet and have it copied to the corresponding sheet. Here is a copy of the code I am using: Sub Copy_To_Worksheets_2() ' This sub uses the functions LastRow and SheetExists Dim CalcMode As Long Dim ws1 As Worksheet Dim ws2 As Worksheet Dim WSNew As Worksheet Dim rng As Range Dim cell As Range Dim Lrow As Long Dim DestRange As Range Dim FieldNum As Integer Dim Lr As Long 'Name of the sheet with your data Set ws1 = Sheets("All") '<<< Change 'Set filter range : A1 is the top left cell of your filter range and 'the header of the first column, D is the last column in the filter range Set rng = ws1.Range("A1:ag" & Rows.Count) 'Set Field number of the filter column 'This example filters on the first field in the range(change the field if needed) 'In this case the range starts in A so Field:=1 is column A, 2 = column B, ...... FieldNum = 33 With Application CalcMode = .Calculation .Calculation = xlCalculationManual .ScreenUpdating = False End With ' Add a worksheet to copy the a unique list and add the CriteriaRange Set ws2 = Worksheets.Add With ws2 'first we copy the Unique data from the filter field to ws2 rng.Columns(FieldNum).AdvancedFilter _ Action:=xlFilterCopy, _ CopyToRange:=.Range("A1"), Unique:=True 'loop through the unique list in ws2 and filter/copy to a worksheet Lrow = .Cells(Rows.Count, "A").End(xlUp).Row For Each cell In .Range("A2:A" & Lrow) If SheetExists(cell.Value) = False Then Set WSNew = Sheets.Add On Error Resume Next WSNew.Name = cell.Value If Err.Number 0 Then MsgBox "Change the name of : " & WSNew.Name & " manually" Err.Clear End If On Error GoTo 0 Set DestRange = WSNew.Range("A1") Else Set WSNew = Sheets(cell.Text) Lr = LastRow(WSNew) Set DestRange = WSNew.Range("A" & Lr + 1) End If 'Firstly, remove the AutoFilter ws1.AutoFilterMode = False 'Filter the range rng.AutoFilter Field:=FieldNum, Criteria1:="=" & cell.Value 'Copy the visible data and use PasteSpecial to paste to the worksheet ws1.AutoFilter.Range.Copy With DestRange .Parent.Select ' Paste:=8 will copy the columnwidth in Excel 2000 and higher .PasteSpecial Paste:=8 .PasteSpecial xlPasteValues .PasteSpecial xlPasteFormats Application.CutCopyMode = False .Select End With ' Delete the header row if you copy to a existing worksheet If Lr 0 Then WSNew.Range("A" & Lr + 1).EntireRow.Delete 'Close AutoFilter ws1.AutoFilterMode = False Lr = 0 Next cell 'Delete the ws2 sheet On Error Resume Next Application.DisplayAlerts = False .Delete Application.DisplayAlerts = True On Error GoTo 0 End With With Application .ScreenUpdating = True .Calculation = CalcMode End With End Sub -- Dave Peterson -- Dave Peterson -- Dave Peterson |
Reply |
Thread Tools | Search this Thread |
Display Modes | |
|
|
![]() |
||||
Thread | Forum | |||
copy rows from one Data sheet to another sheet based on cell conte | Excel Discussion (Misc queries) | |||
Auto Copy/autofill Text from sheet to sheet if meets criteria | Excel Discussion (Misc queries) | |||
Copy Sheet causes Combo Box change event to fire on original sheet | Excel Programming | |||
Help: auto-copy entire rows from 1 sheet (based on cell criteria) to another sheet. | Excel Programming | |||
relative sheet references ala sheet(-1)!B11 so I can copy a sheet. | Excel Discussion (Misc queries) |