Error with a Range selection - excel

I have some problems with a piece of code. I get an error when it has to select a range
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim valrand As Long
If Intersect(Target, ActiveCell) = "Insert line" Then
valrand = ActiveCell.Row
If Worksheets("IR").Cells(valrand, 18).Value <> 5 Then
Sheets("Format").Select
MsgBox ("Format")
Range("A13:N13").Select 'here's the error
Selection.Copy
Sheets("IR").Select
Range("A" & valrand + 2 + Worksheets("IR").Cells(12, 18) & ":N" & valrand + 2 + Worksheets("IR").Cells(12, 18)).Select
Selection.Insert Shift:=xlDown
Range("A38:N38").Select
Application.CutCopyMode = False
Selection.Delete Shift:=xlUp
Range("A5").Select
contor = Worksheets("IR").Cells(12, 18).Value + 1
Worksheets("IR").Cells(12, 18).Value = contor
End If
End If
End Sub
Where I put the commet "here's the error" it gives me "Select method of Range class failed"
What am I doing wrong? Usually this piece of code worked before I added in the SelectionChange code block.
Thanks!

You should look at avoiding Select when using Sheet code (best to avoid it altogether, more later on this) and use something like this instead
Application.Goto Sheets("Format").Range("A13:N13")
(I had tried fully qualifying the reference but this only worked if I used
Sheets("Format").Select
Sheets("Format").Range("A13:N13").Select
which is clearly overkill)
While that solves you immediate issue you should look at consolidating your code, for example
Disabling Events so that other sheet events dont fire while your Select is running
Removing any Select statements
This is an example of what may work better (now with no sheet activation)
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim lngRand As Long
Dim rng1 As Range
Set ws1 = Sheets("Format")
Set ws2 = Sheets("IR")
If Intersect(Target, ActiveCell) = "Insert line" Then
lngRand = ActiveCell.Row
If ws2.Cells(lngRand, 18).Value <> 5 Then
Application.EnableEvents = False
Set rng1 = Range("A" & lngRand + 2 + ws2.Cells(12, 18))
'extend rng1 from column A to colum N
Set rng1 = rng1.Resize(rng1.Rows.Count, 14)
ws2.Range(rng1.Address).Insert xlDown
'copy Format to IR
ws1.Range("A13:N13").Copy ws2.Range(rng1.Address)
'Update Format
ws2.Range("A38:N38").Delete Shift:=xlUp
ws2.Cells(12, 18).Value = ws2.Cells(12, 18).Value + 1
Application.EnableEvents = True
End If
End If
End Sub

Related

FormulaR1C1 not running across a selected range

I'm trying to make a macro where I can find a set of products and get an average weekly sales figure. However, FormulaR1C1 is only applying to the first figure in a selection and not all active cells. Any help as to why it doesn't apply for the whole range?
Option Compare Text
Private Sub submit_Click()
Dim emptyRow As Long
Dim Rng As Range
Dim myCell As Object
Dim mySelection As Range
Range("R1:S1").Select
Range("R1:S1").Clear
ActiveCell.FormulaR1C1 = ""
emptyRow = WorksheetFunction.CountA(Range("R:R")) + 1
Cells(emptyRow, 18).Value = search.Value
Cells(emptyRow, 19).Value = week.Value
Set Rng = Range("A1:A2000")
searchString = Range("R1")
For Each myCell In Rng
If InStr(myCell.Text, searchString) Then
If Not mySelection Is Nothing Then
Set mySelection = Union(mySelection, myCell)
Else
Set mySelection = myCell
End If
End If
Next
If mySelection Is Nothing Then
MsgBox "The product was not found in the selection"
Else
mySelection.Offset(0, 4).Select
End If
ActiveCell.FormulaR1C1 = "=RC[-2] /" & Range("S1")
Unload Me
End Sub
The selection may contain more than one cell, but only one is the active cell.
If mySelection Is Nothing Then
MsgBox "The product was not found in the selection"
Else
mySelection.Offset(, 4).FormulaR1C1 = "=RC[-2] /" & Range("S1")
End If

Macro Running Out Of Memory When Run Twice

I am new to this forum but have been reading a large number of posts recently as I am currently self teaching VBA for use at work!
I currently am having an issue with a bit of code that I have created. The aim of the code is to autofilter multiple sheets depending on a cell value that is double clicked on, it then copies these filtered results to another "Master Report" sheet. The issue is that it runs perfectly fine once, after which if I try to run it again or any of my other macro's within the workbook an error pops up asking me to close things to free up memory!
I have tried running the macro once, saving and closing the workbook (to clear anything that might be cached), re-opening and running and yet the same error persists. I also tried changing my .select prompts with .activate as suggested by:
How to avoid running out of memory when running VBA
but that seemed to break my code... then again I may have just implemented it wrong as I am a bit of a VBA noob Can anyone help me optimize my code to prevent this?
my code is as below:
Private Sub Merge()
With Selection
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlBottom
End With
Selection.Merge
End Sub
-------------------------------------------------------------------------------------------------------------------------------------------------------
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Cancel = True
Application.ScreenUpdating = False
Application.EnableEvents = False
Sheets("Master Report").Cells.Delete 'clear old master report
Column = Target.Column
Row = Target.Row
'this automatically filters information for a single part and creates a new master report with summary information
PartNumber = Cells(Row, 2).Value 'capture target part number for filtering
PartDesc = Cells(Row, 7).Value 'capture target part description
PartNumberWildCard = "*" & PartNumber & "*" 'add wildcards to allow for additional terms
With Worksheets("NCR's") 'filter NCR sheet
.Select
On Error Resume Next
ActiveSheet.ShowAllData 'remove any previous filters
On Error GoTo 0
.Range("A1").AutoFilter Field:=2, Criteria1:=PartNumberWildCard
End With
Sheets("NCR's").Select
Sheets("NCR's").Range("A3:K3").Select
Sheets("NCR's").Range(Selection, Selection.End(xlDown)).Select 'select NCR filtered summary info
Selection.Copy
Sheets("Master Report").Select
Sheets("Master Report").Range("A1").Formula = PartNumber
Sheets("Master Report").Range("D1").Formula = PartDesc 'Print part no. & description at top of master report
Sheets("Master Report").Range("A4").Select
ActiveSheet.Paste 'paste filtered NCR info into master report
Sheets("Master Report").Range("A3:K3").Select
Call Merge
ActiveCell.FormulaR1C1 = "NCR's"
With Worksheets("CR's") 'filter CR sheet
.Select
On Error Resume Next
ActiveSheet.ShowAllData 'remove any previous filters
On Error GoTo 0
.Range("A1").AutoFilter Field:=3, Criteria1:=PartNumberWildCard
End With
Sheets("CR's").Select
Sheets("CR's").Range("A7:F7").Select
Sheets("CR's").Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Sheets("Master Report").Select
Sheets("Master Report").Range("P4").Select
ActiveSheet.Paste
Sheets("Master Report").Range("RP3:U3").Select
Call Merge
ActiveCell.FormulaR1C1 = "CR's"
With Worksheets("PO's") 'filter PO sheet
.Select
On Error Resume Next
ActiveSheet.ShowAllData 'remove any previous filters
On Error GoTo 0
.Range("A1").AutoFilter Field:=2, Criteria1:=PartNumberWildCard
End With
Sheets("PO's").Select
Sheets("PO's").Range("A3:H3").Select
Sheets("PO's").Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Sheets("Master Report").Select
lastRow = Sheets("Master Report").Range("A" & Rows.Count).End(xlUp).Row
lastRow = lastRow + 3
Sheets("Master Report").Range("A" & lastRow).Select
ActiveSheet.Paste
Sheets("Master Report").Range("A" & lastRow - 1 & ":H" & lastRow - 1).Select
Call Merge
ActiveCell.FormulaR1C1 = "PO's"
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
Another piece of info that may help is that I tried removing the last of the three filter/copy/paste routines, this allowed me to run the code about 3 times before running into the same memory error. Also the Debugger always gets stuck on the command to clear the master report at the beginning of the macro
Sheets("Master Report").Cells.Delete 'clear old master report
There are a couple of tips to speed up your macro and make it use less memory (less selecting, copying pasting). For a start it would be better to loop through your sheets rather than one long script for every one.
Dim arrShts As Variant, arrSht As Variant
arrShts = Array("NCR's", "CR's", "PO's")
For Each arrSht In arrShts
Worksheets(arrSht).Activate
'rest of your code'
Next arrSht
In the array add any other sheets you need to run the script on
Declaring variables is recommended also:
Dim masterws As Worksheet
Set masterws = Sheets("Master Report")
masterws.Activate
masterws.Range("A1").Formula = PartNumber
I haven't been able to do this 100% accurately, but you could limit your code down to something like the following
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Cancel = True
Application.ScreenUpdating = False
Application.EnableEvents = False
Column = Target.Column
Row = Target.Row
PartNumber = Cells(Row, 2).Value 'capture target part number for filtering
PartDesc = Cells(Row, 7).Value 'capture target part description
PartNumberWildCard = "*" & PartNumber & "*" 'add wildcards to allow for additional terms
Dim arrShts As Variant, arrSht As Variant, lastrw As Integer
Dim masterws As Worksheet
Set masterws = Sheets("Master Report")
masterws.Cells.Clear 'clear old master report
arrShts = Array("NCR's", "CR's", "PO's")
For Each arrSht In arrShts
Worksheets(arrSht).Activate
lastrw = Sheets(arrSht).Range("K" & Rows.Count).End(xlUp).Row
With Worksheets(arrSht) 'filter NCR sheet
On Error Resume Next
ActiveSheet.ShowAllData 'remove any previous filters
On Error GoTo 0
.Range("A1").AutoFilter Field:=2, Criteria1:=PartNumberWildCard
End With
Range(Cells(3, 1), Cells(lastrw, 11)).Copy
lastRow = Sheets("Master Report").Range("A" & Rows.Count).End(xlUp).Row
masterws.Activate
masterws.Range("A1").Formula = PartNumber
masterws.Range("D1").Formula = PartDesc 'Print part no. & description at top of master report
masterws.Range("A" & lastRow).PasteSpecial xlPasteValues
masterws.Range("A" & lastRow - 1 & ":H" & lastRow - 1).Select
Call Merge
ActiveCell.FormulaR1C1 = arrSht
Application.CutCopyMode = False
Next arrSht
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
This is in no way complete, and will edit as I find bits, but a good place to start to reduce the strain of your macro.
try this refactoring of your code
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, cancel As Boolean)
Dim iRow As Long
Dim PartNumber As String, PartDesc As String, PartNumberWildCard As String
Dim masterSht As Worksheet
Set masterSht = Worksheets("Master Report")
cancel = True
iRow = Target.Row
PartNumber = Cells(iRow, 2).Value 'capture target part number for filtering
PartDesc = Cells(iRow, 7).Value 'capture target part description
PartNumberWildCard = "*" & PartNumber & "*" 'add wildcards to allow for additional terms
'clear old master report and write headers
With masterSht
.Cells.ClearContents
.Cells.UnMerge
.Range("A1").Value = PartNumber
.Range("D1").Value = PartDesc 'Print part no. & description at top of master report
FilterAndPaste "NCR's", "K1", 2, PartNumberWildCard, .Range("A4")
FilterAndPaste "CR's", "F1", 3, PartNumberWildCard, .Range("P4")
FilterAndPaste "PO's", "H1", 2, PartNumberWildCard, .Cells(rows.count, "A").End(xlUp).Offset(3)
End With
End Sub
Sub FilterAndPaste(shtName As String, lastHeaderAddress As String, fieldToFilter As Long, criteria As String, targetCell As Range)
With Worksheets(shtName)
.AutoFilterMode = False 'remove any previous filters
With .Range(lastHeaderAddress, .Cells(.rows.count, 1).End(xlUp))
.AutoFilter Field:=fieldToFilter, Criteria1:=criteria
If Application.WorksheetFunction.Subtotal(103, .Resize(, 1)) > 1 Then
.Resize(.rows.count - 1).Offset(1).SpecialCells(XlCellType.xlCellTypeVisible).Copy Destination:=targetCell
With targetCell.Offset(-1).Resize(, .Columns.count)
Merge .Cells
.Value = shtName
End With
End If
End With
End With
End Sub
Private Sub Merge(rng As Range)
With rng
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlBottom
.Merge
End With
End Sub
should it work for you, as it did in my tests, then I can add you some info, if you care about

Excel - How to fill in empty lines below with current value until new value is met in the same column. Non-VBA solution needed [duplicate]

I want to fill in all empty cells using values of above cells
state name
IL Mike
Sam
CA Kate
Bill
Leah
Should be as follows
state name
IL Mike
IL Sam
CA Kate
CA Bill
CA Leah
I tried the following
Sub split()
Dim columnValues As Range, i As Long
Set columnValues = Selection.Area
Set i = 1
For i = 1 To columnValues.Rows.Count
If (columnValues(i) = "") Then
columnValues(i) = columnValues(i - 1)
End If
Next
End Sub
I get an error when I set i. How can I modify my code
For those not requiring VBA for this, select ColumnA, Go To Special..., Blanks and:
Equals (=), Up (▲), Ctrl+Enter
should give the same result.
Given you asked for VBA, there is a quicker way than looping (the VBA equivalent of what pnuts posed above, with the additional step of removing the formula at the end):
On Error Resume Next
With Selection.SpecialCells(xlCellTypeBlanks)
.FormulaR1C1 = "=R[-1]C"
.Value = .Value
End With
It is because i should be defined as i=1. There are although a few other problems with the code. I would change it to something like this:
Sub split()
Dim columnValues As Range, i As Long
Set columnValues = Selection
For i = 1 To columnValues.Rows.Count
If columnValues.Cells(i, 1).Value = "" Then
columnValues.Cells(i, 1).Value = columnValues.Cells(i - 1, 1).Value
End If
Next
End Sub
Sub fill_blanks()
Dim i As Long
i = 2 ' i<>1 because your first raw has headings "state " "name"
'Assume state is in your cell A and name is in your cell B
Do Until Range("B" & i) = ""
Range("B" & i).Select
If ActiveCell.FormulaR1C1 <> "" Then
Range("A" & i).Select
If ActiveCell.FormulaR1C1 = "" Then
Range("A" & i - 1).Copy
Range("A" & i).PasteSpecial Paste:=xlPasteValues
Else
i = i + 1
End If
Else
i = i + 1
End If
Loop
End Sub
For some cause the method used on post https://stackoverflow.com/a/20439428/2684623 not work for me. When the line .value=.value is executed, I get the error 'not available' (#N/D for local language) in the value of cells. Version of Office is 365.
I dont know the reason however with some modifications runs fine:
Sub TLD_FillinBlanks()
On Error Resume Next
With ActiveSheet.UsedRange.Columns(1)
If .Rows(1) = "" Then .Rows(1).Value = "'"
.SpecialCells(xlCellTypeBlanks).FormulaR1C1 = "=R[-1]C"
.Value = .Value
End With
End Sub
Using loops:
Sub TLD_FillinBlanksLoop()
Dim rCell As Range
For Each rCell In ActiveSheet.UsedRange.Columns(1).Cells
If rCell.Value = "" And rCell.Row > 1 Then
rCell.FillDown
End If
Next
End Sub
I hope that can be useful for somebody. Thanks and regards.
Here is the whole module, I pasted the formulas as values at the end.
Sub FillBlanksValueAbove()
Dim sName As String
sName = ActiveSheet.Name
Dim ws As Worksheet
Dim lastRow As Long, lastCol As Long
Dim rng As Range
'Set variable ws Active Sheet name
Set ws = Sheets(sName)
With ws
'Get the last row and last column
lastRow = .Range("A" & .Rows.Count).End(xlUp).Row
lastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
'Set the range
Set rng = .Range(.Cells(1, 1), .Cells(lastRow, lastCol))
rng.Select
'Select Blanks
rng.SpecialCells(xlCellTypeBlanks).Select
'Fill Blanks with value above
Selection.FormulaR1C1 = "=R[-1]C"
'Paste Formulas as Values
rng.Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:= _
xlNone, SkipBlanks:=False, Transpose:=False
End With
End Sub

Filling any empty cells with the value above

I want to fill in all empty cells using values of above cells
state name
IL Mike
Sam
CA Kate
Bill
Leah
Should be as follows
state name
IL Mike
IL Sam
CA Kate
CA Bill
CA Leah
I tried the following
Sub split()
Dim columnValues As Range, i As Long
Set columnValues = Selection.Area
Set i = 1
For i = 1 To columnValues.Rows.Count
If (columnValues(i) = "") Then
columnValues(i) = columnValues(i - 1)
End If
Next
End Sub
I get an error when I set i. How can I modify my code
For those not requiring VBA for this, select ColumnA, Go To Special..., Blanks and:
Equals (=), Up (▲), Ctrl+Enter
should give the same result.
Given you asked for VBA, there is a quicker way than looping (the VBA equivalent of what pnuts posed above, with the additional step of removing the formula at the end):
On Error Resume Next
With Selection.SpecialCells(xlCellTypeBlanks)
.FormulaR1C1 = "=R[-1]C"
.Value = .Value
End With
It is because i should be defined as i=1. There are although a few other problems with the code. I would change it to something like this:
Sub split()
Dim columnValues As Range, i As Long
Set columnValues = Selection
For i = 1 To columnValues.Rows.Count
If columnValues.Cells(i, 1).Value = "" Then
columnValues.Cells(i, 1).Value = columnValues.Cells(i - 1, 1).Value
End If
Next
End Sub
Sub fill_blanks()
Dim i As Long
i = 2 ' i<>1 because your first raw has headings "state " "name"
'Assume state is in your cell A and name is in your cell B
Do Until Range("B" & i) = ""
Range("B" & i).Select
If ActiveCell.FormulaR1C1 <> "" Then
Range("A" & i).Select
If ActiveCell.FormulaR1C1 = "" Then
Range("A" & i - 1).Copy
Range("A" & i).PasteSpecial Paste:=xlPasteValues
Else
i = i + 1
End If
Else
i = i + 1
End If
Loop
End Sub
For some cause the method used on post https://stackoverflow.com/a/20439428/2684623 not work for me. When the line .value=.value is executed, I get the error 'not available' (#N/D for local language) in the value of cells. Version of Office is 365.
I dont know the reason however with some modifications runs fine:
Sub TLD_FillinBlanks()
On Error Resume Next
With ActiveSheet.UsedRange.Columns(1)
If .Rows(1) = "" Then .Rows(1).Value = "'"
.SpecialCells(xlCellTypeBlanks).FormulaR1C1 = "=R[-1]C"
.Value = .Value
End With
End Sub
Using loops:
Sub TLD_FillinBlanksLoop()
Dim rCell As Range
For Each rCell In ActiveSheet.UsedRange.Columns(1).Cells
If rCell.Value = "" And rCell.Row > 1 Then
rCell.FillDown
End If
Next
End Sub
I hope that can be useful for somebody. Thanks and regards.
Here is the whole module, I pasted the formulas as values at the end.
Sub FillBlanksValueAbove()
Dim sName As String
sName = ActiveSheet.Name
Dim ws As Worksheet
Dim lastRow As Long, lastCol As Long
Dim rng As Range
'Set variable ws Active Sheet name
Set ws = Sheets(sName)
With ws
'Get the last row and last column
lastRow = .Range("A" & .Rows.Count).End(xlUp).Row
lastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
'Set the range
Set rng = .Range(.Cells(1, 1), .Cells(lastRow, lastCol))
rng.Select
'Select Blanks
rng.SpecialCells(xlCellTypeBlanks).Select
'Fill Blanks with value above
Selection.FormulaR1C1 = "=R[-1]C"
'Paste Formulas as Values
rng.Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:= _
xlNone, SkipBlanks:=False, Transpose:=False
End With
End Sub

Error 1004 when trying to offset active cell

I am trying to offset the active cell until a certain condition is met. What I've written is
Do While ActiveCell.Value <> Worksheets("Unit B").Range("D1").Value
ActiveCell.Offset(0, 1).Select
Loop
Can you please help me correct this ?
Giving my entire code for reference:
Private Sub CommandButton1_Click()
Dim ddsdata As Range
Dim i As Long
i = 1
Worksheets("Unit B").Select
Set ddsdata = Worksheets("Unit B").Range("E3:E35")
Worksheets("Data Sheet").Select
Worksheets("Data Sheet").Range("E1").Select
Do While ActiveCell.Offset(0, i) <> Worksheets("Unit B").Range("D1").Value
i = i + 1
Loop
ActiveCell.Offset(1, i).Select
ActiveCell.Value = ddsdata
Try below code. Avoid using Select / Activate / ActiveCell in your code. Also always refer a cell by sheetname then the cell. eg Sheet1.Range("A1") in a workbook for better results.
Private Sub CommandButton1_Click()
Dim ddsdata As Range
Dim i As Long
i = 1
Thisworkoook.Activate
Set ddsdata = Thisworkoook.Sheets("Unit B").Range("E3:E35")
Do While Worksheets("Data Sheet").Range("E1").Offset(0, i) <> Worksheets("Unit B").Range("D1").Value
i = i + 1
Loop
ActiveCell.Offset(1, i).Select
ActiveCell.Value = ddsdata
End Sub

Resources