VBA code crashing Excel if closed early - vba

Hello again and thank you for time !
I have the following code that would not let me work in peace - although I am no VBA power I have managed to put this together in about a week or so.
After launching the macro, most of the times I must not touch excel at all for ~2 minutes but I do have occasions for which it closes by itself ...
Sub Filter()
'
' substitute Macro
Application.ScreenUpdating = False
Selection.Copy
ActiveWindow.ActivateNext
Sheets.Add After:=Sheets(Sheets.Count)
ActiveSheet.Name = "buffer"
Dim wsS As Worksheet, wsN As Worksheet, i As Integer, j As Integer, k As Integer, l As Integer
Set wsS = Sheets("buffer")
Set wsN = Sheets("non_confid")
colA = "A"
colB = "B"
colC = "C"
colE = "E"
i = 2
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Selection.Replace What:=" ", Replacement:=","
Range("A1").Copy
Range("z1").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Columns("A:y").Select
Range("F25").Activate
Application.CutCopyMode = False
Selection.Delete Shift:=xlToLeft
Range("B1").FormulaR1C1 = "=SUBSTITUTE(RC[-1],CHAR(13),"";"")"
Range("C1").FormulaR1C1 = "=SUBSTITUTE(RC[-1],CHAR(10),"";"")"
Range("D1").FormulaR1C1 = "=substitute(rc[-1],""/"","";"")"
Range("e1").FormulaR1C1 = "=substitute(rc[-1],""consultant"","";"")"
Range("f1").FormulaR1C1 = "=substitute(rc[-1],""dessinateur"","";"")"
Range("g1").FormulaR1C1 = "=substitute(rc[-1],""grp"","";"")"
Range("h1").FormulaR1C1 = "=substitute(rc[-1],""projet"","";"")"
Range("i1").FormulaR1C1 = "=substitute(rc[-1],""Inscrire dans ce pavé les projets ou familles concernés"","";"")"
Range("j1").FormulaR1C1 = "=substitute(rc[-1],""Inscrire dans ce pavé les profils demandés"","";"")"
Range("k1").FormulaR1C1 = "=substitute(rc[-1],""Droits en consultation"","";"")"
Range("l1").FormulaR1C1 = "=substitute(rc[-1],""Droits en création"","";"")"
Range("m1").FormulaR1C1 = "=substitute(rc[-1],"":"","";"")"
Range("n1").FormulaR1C1 = "=substitute(rc[-1],""("","";"")"
Range("o1").FormulaR1C1 = "=substitute(rc[-1],"")"","";"")"
Range("p1").FormulaR1C1 = "=substitute(rc[-1],""profil"","";"")"
Range("q1").FormulaR1C1 = "=substitute(rc[-1],""non,confid"","";"")"
Range("r1").FormulaR1C1 = "=substitute(rc[-1],"" "","";"")"
Range("r1").Copy
Range("s2").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Rows("1:1").Select
Application.CutCopyMode = False
Selection.Delete Shift:=xlUp
Columns("A:r").Select
Selection.Delete Shift:=xlToLeft
Range("A1").Select
Selection.TextToColumns Destination:=Range("A1"), DataType:=xlDelimited, TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=True, Tab:=True, Semicolon:=True, Comma:=True, Space:=False, OtherChar:="/", FieldInfo:=Array(Array(1, 1), Array(2, 1), Array(3, 1), Array(4, 1), Array(5, 1), Array(6, 1), Array(7, 1), Array(8, 1), Array(9, 1), Array(10, 1), Array(11, 1), Array(12, 1), Array(13, 1), Array(14, 1), Array(15, 1), Array(16, 1), Array(17, 1), Array(18, 1), Array(19, 1), Array(20, 1), Array(21, 1), Array(22, 1), Array(23, 1), Array(24, 1), Array(25, 1), Array(26, 1), Array(27, 1), Array(28, 1), Array(29, 1), Array(30, 1))
Range(Selection, Selection.End(xlToRight)).Copy
Range("A2").PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:=False, Transpose:=True
Rows("1:1").Select
Application.CutCopyMode = False
Selection.Delete Shift:=xlUp
Columns("A:A").EntireColumn.AutoFit
Rows("1:1").Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
Range("a1").FormulaR1C1 = "Sorted"
Range("a1").Select
ActiveSheet.Range("$A$1:$A$300").RemoveDuplicates Columns:=1, Header:=xlNo
ActiveSheet.ListObjects.Add(xlSrcRange, Range("$A$1:$a$500"), , xlYes).Name = "Table1"
ActiveSheet.ListObjects("Table1").Range.AutoFilter Field:=1, Criteria1:="<>"
Range("B2").Select
ActiveCell.FormulaR1C1 = _
"=IFERROR(IF(ISNA(MATCH([#Sorted],NPDM[Contexte],0)),IF(FIND(""."",[#Sorted]),[#Sorted],""""),""""),"""")"
Range("B1").FormulaR1C1 = "Formula"
Range("Table1[Formula]").Select
Selection.Copy
Range("C2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Columns("B:B").Select
Application.CutCopyMode = False
Selection.Delete Shift:=xlToLeft
Range("B1").FormulaR1C1 = "Dot"
Range("Table1[Dot]").Select
Selection.TextToColumns Destination:=Range("Table1[[#Headers],[Dot]]"), _
DataType:=xlDelimited, TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter _
:=True, Tab:=True, Semicolon:=True, Comma:=True, Space:=False, Other _
:=True, OtherChar:=".", FieldInfo:=Array(Array(1, 1), Array(2, 1)), _
TrailingMinusNumbers:=True
Range("C1").FormulaR1C1 = "nDot"
Range("B1").FormulaR1C1 = "Dot"
Range("Table1[Dot]").Select
Selection.Copy
Range("A250").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=True, Transpose:=False
Range("Table1[nDot]").Select
Selection.Copy
Range("A500").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=True, Transpose:=False
Range("B:C").EntireColumn.Delete
For j = 2 To 300
If Not IsEmpty(wsS.Range(colA & j).Value) Then
wsS.Range(colC & i - 1).Value = wsS.Range(colA & j).Value
i = i + 1
End If
Next
Range("A:B").EntireColumn.Delete
For k = 1 To 300
If Not IsEmpty(wsS.Range(colA & k).Value) Then
wsN.Range(colE & i).Value = wsS.Range(colA & k).Value
i = i + 1
End If
Next
Sheets("non_confid").Select
Columns("A:G").EntireColumn.AutoFit
Range("e1").Select
ActiveSheet.ListObjects("Status").Range.AutoFilter Field:=4, Criteria1:="<>"
Range("E2").Select
ActiveWorkbook.Worksheets("non_confid").ListObjects("Status").Sort.SortFields. _
Clear
ActiveWorkbook.Worksheets("non_confid").ListObjects("Status").Sort.SortFields. _
Add Key:=Range("Status[ce ?]"), SortOn:=xlSortOnValues, Order:= _
xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("non_confid").ListObjects("Status").Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Range("A1").Select
Application.DisplayAlerts = False
Sheets("buffer").Select
ActiveWindow.SelectedSheets.Delete
Application.DisplayAlerts = True
ActiveWorkbook.Saved = True
Application.ScreenUpdating = True
End Sub
PS - since my team mates will be working with this, is there a way for this macro to work on a PC that is in French ? because in an earlier version was not (making "Feuil1" while looking for "Sheet1" and putting formulas in English instead of translating them). As I understood, the macro convert automatically to an universal programming language to be read wherever they are opened.

Cor_Blimey gave you some great information above. I will add to this.
Your code can probably be improved if you learn to avoid the Select and Activate methods (which force you to rely on bulkier, cumbersome code that takes longer to execute). It also makes for code that is not as easily legible, because it's not as object-oriented.
Also, many people rely unnecessarily on Copy & Paste methods, when that can also usually be avoided.
Here is one such example, where you copy a range and then paste values to another range:
Range("A1").Copy
Range("z1").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
This can be simplified like:
Range("Z1").Value = Range("A1").Value
Here is an example of unnecessary Select method:
Rows("1:1").Select
Application.CutCopyMode = False
Selection.Delete Shift:=xlUp
These three lines of code can be replaced with one statement:
Rows("1:1").EntireRow.Delete
And another (there are several examples of such):
Range("B2").Select
ActiveCell.FormulaR1C1 = _
"=IFERROR(IF(ISNA(MATCH([#Sorted],NPDM[Contexte],0)),IF(FIND(""."",[#Sorted]),[#Sorted],""""),""""),"""")"
In the above, you first select/activate a cell, and then you operate on the ActiveCell. This is unnecessary, you can simply operate on the object directly:
Range("B2").FormulaR1C1 = "=IFERROR(IF(ISNA(MATCH([#Sorted],NPDM[Contexte],0)),IF(FIND(""."",[#Sorted]),[#Sorted],""""),""""),"""")"
THese are some helpful coding practices. Otherwise, #Cor_Blimey's answer above is very good. The Application.ScreenUpdating should speed up the execution time, and if possible, setting Application.Calculation = xlManual will also help. However, the .Calculation method might not be an option in this case, since you may be relying on interim calculations as you're moving .Values from one range to another.

For non english languages, you could use .FormulaLocal or .FormulaR1C1Local. Developer reference says "Returns or sets the formula for the object, using R1C1-style notation in the language of the user. Read/write Variant".
However, I strongly recommend not using the above, as it will mean it won't work if the macro is run on a different language version. Instead, better practice is to use English in conjunction with .Formula and .FormulaR1C1. This will still open as French in a French version, as Excel automatically displays formulae text in the relevant language.
For example: (I use "FALSE" only as an example - the below is true for formulae too like "=SUM(A1)", and of course, if you really want to set a boolean value then please don't use string "TRUE"!)
ActiveCell.Formula = "FALSE"
Ok - Locale independent - This will be a FALSE boolean value displayed as FALSE in English and displayed as FAUX in French, but in both cases it is a Boolean value
ActiveCell.FormulaLocal = "FAUX"
'Bad - Locale dependent! - This will be a String "FAUX" if the macro is run on an English version,
but a boolean FALSE if run on a French version
ActiveCell.Formula = "FAUX"
'Locale independent, but probably not what you want - This will be a String "FAUX" in all languages
You should not hard-code referring to a sheet by something like "Feuil1". This is just a string name, and Excel will not adapt for the User's locale. Instead, when you add a new sheet, immediately assign it to a worksheet variable, then use that.
For example:
'Bad: it might work if the workbook is made on a French version but it won't on English and vice versa
Worksheets("Feuil1").Activate
Worksheets("Sheet1").Activate 'also bad
'Better:
Worksheets(1).Activate
'or
With Worksheets.Add
.Name = "Results"
.Activate
End With
'or (for use outside a With block)
Set resultsWs = Worksheets.Add
As for the rest - I am afraid I do not know what your question is. It is probably crashing sometimes because you are using lots of cut/copy - if it is a very large worksheet or with lots of formulae that recalculate each cut/insert this will take a long time. Unless you need intermediate calculations, disable calculation and screen updating at the start and only re-enable at the end (using Application.ScreenUpdating = False, and Application.Calculation = XLManual)

Related

No errors, but Macro works using F8 line by line, not when executing the full macro - excel, vba

I have 6 identical macros in one workbook. 4 out of 6 work good, but I have the same issue for the rest.
If I run the macro from debug window with F8, I have perfect , expected results. If I run a macro normally, I have not any errors, but the result is obviously wrong.
I can guess that at that case , that the macto ignores this part (all mistakes start here), but not sure
ActiveSheet.Range("H2").Select
ActiveCell.FormulaR1C1 = "=COUNTIF(C[-3],RC[-3])"
ActiveSheet.Range("H2").Select
Selection.AutoFill Destination:=Range("H2:H" & lastrow)
ActiveSheet.Range("H2:H" & lastrow).Select
The goal of the macro is to filter one tab, put a few columns in another tab; compare values from one of the columns to another tab, remove duplicates , filter and paste the results in the "Results" tab.
When I do this manually I have got 6 rows in a "Result" tab. When I run it normally, I have one row, or nothing..
Can you please kindly advise - what is wrong with this macro?
I have tried to put this line in my code (no luck) :
Application.PrintCommunication = True
I have tried to put DoEvents
ThisWorkbook before each Row, Column and Range - no luck
Many thanks in advance!!
And here is my full code:
Public lastrow As Long
Public FileName As String
Public TabName As String
Sub APP_filtering_new()
'
' APP_filtering Macro
lastrow = ActiveSheet.Range("A1048576").End(xlUp).Row
Sheets("APP-input").Select
ActiveSheet.Rows("1:1").Select
Selection.AutoFilter
ActiveSheet.Range("$A$1:$AG$14878").AutoFilter Field:=2, Criteria1:=Array( _
"BRAMPTON", "VANCOUVER, CD", "VANCOUVER", _
"VANCOUVER TERMINAL"), Operator:=xlFilterValues
ActiveSheet.Columns("E:E").Select
Selection.SpecialCells(xlCellTypeVisible).Select
Selection.Copy
Sheets("APP_output").Select
ActiveSheet.Columns("A:A").Select
ActiveSheet.Paste
Sheets("APP-input").Select
ActiveSheet.Columns("N:N").Select
Selection.SpecialCells(xlCellTypeVisible).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("APP_output").Select
ActiveSheet.Columns("D:D").Select
ActiveSheet.Paste
Sheets("APP-input").Select
ActiveSheet.Columns("G:G").Select
Selection.SpecialCells(xlCellTypeVisible).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("APP_output").Select
ActiveSheet.Columns("E:E").Select
ActiveSheet.Paste
ActiveSheet.Range("F2").Select
Application.CutCopyMode = False
ActiveCell.FormulaR1C1 = " "
ActiveSheet.Range("F2").Select
Selection.AutoFill Destination:=Range("F2:F" & lastrow)
ActiveSheet.Range("F2:F" & lastrow).Select
ActiveSheet.Range("G2").Select
ActiveCell.FormulaR1C1 = " "
ActiveSheet.Range("G2").Select
Selection.AutoFill Destination:=Range("G2:G" & lastrow)
ActiveSheet.Range("G2:G" & lastrow).Select
ActiveSheet.Range("H2").Select
ActiveCell.FormulaR1C1 = "=COUNTIF(C[-3],RC[-3])"
ActiveSheet.Range("H2").Select
Selection.AutoFill Destination:=Range("H2:H" & lastrow)
ActiveSheet.Range("H2:H" & lastrow).Select
ActiveSheet.Columns("H:H").Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'remove duplicates
ActiveSheet.Columns("A:H").Select
Application.CutCopyMode = False
ActiveSheet.Range("A1:E" & lastrow).RemoveDuplicates Columns:=5, Header:= _
xlNo
'vlookup, IF condition
ActiveSheet.Range("I2").Select
ActiveCell.FormulaR1C1 = "=VLOOKUP(RC[-4],container,4,FALSE)"
ActiveSheet.Range("I2").Select
Selection.AutoFill Destination:=Range("I2:I" & lastrow)
ActiveSheet.Range("I2:I" & lastrow).Select
ActiveSheet.Range("J2").Select
ActiveCell.FormulaR1C1 = _
"=IF(RC[-1]<RC[-2],""C. has bigger number of Containers"",IF(RC[-1]=RC[-2],""The same amount of containers"",IF(RC[-2]<RC[-1],""The C. has less amount of Containers"")))"
ActiveSheet.Range("J2").Select
Selection.AutoFill Destination:=Range("J2:J" & lastrow)
ActiveSheet.Range("J2:J" & lastrow).Select
ActiveSheet.Range("H1").Select
ActiveCell.FormulaR1C1 = "Amt of Containers - External report"
ActiveSheet.Range("I1").Select
ActiveCell.FormulaR1C1 = "Amt of Containers - Internal report"
ActiveSheet.Range("J1").Select
ActiveCell.FormulaR1C1 = "Result (N/A means New Shipment)"
ActiveSheet.Range("H1:J1").Select
With Selection
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlBottom
.WrapText = True
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
End With
With Selection
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlTop
.WrapText = True
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
End With
ActiveSheet.Range("H1:I1").Select
ActiveSheet.Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
ActiveSheet.Range("J1").Select
ActiveSheet.Range(Selection, Selection.End(xlDown)).Select
Application.CutCopyMode = False
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
ActiveSheet.Range("J1").Select
Application.CutCopyMode = False
Selection.AutoFilter
ActiveSheet.Range("D1:J" & lastrow).AutoFilter Field:=7, Criteria1:=Array( _
"#N/A", "C. has bigger number of Containers", _
"The C. has less amount of Containers"), Operator:=xlFilterValues
' paste in next empty row
ActiveSheet.Rows("2:2").Select
ActiveSheet.Range(Selection, Selection.End(xlDown)).Select
Selection.SpecialCells(xlCellTypeVisible).Select
Selection.Copy
Sheets("Results").Select
lastrow = ActiveSheet.Range("A1048576").End(xlUp).Row
ActiveSheet.Range("A" & lastrow + 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End Sub
This isn't a full answer, but e.g this block of code
ActiveSheet.Range("H2").Select
ActiveCell.FormulaR1C1 = "=COUNTIF(C[-3],RC[-3])"
ActiveSheet.Range("H2").Select
Selection.AutoFill Destination:=Range("H2:H" & lastrow)
ActiveSheet.Range("H2:H" & lastrow).Select
can be replaced by a single line
ActiveSheet.Range("H2:H" & lastrow).FormulaR1C1 = "=COUNTIF(C[-3],RC[-3])"
Get rid of ActiveSheet and replace with the actual sheet name.

How do i combine macro module with the rest of the code

I'm a beginner, so any help is much appreciated, I want to combine this macro with the first code, but I don't know how to do that or where to put it.
this is the first code (it has a mistake in it, but I already have an answer on how to fix it, so it's alright):
Sub foo()
Dim ws As Worksheet: Set ws = Sheets("inbd")
Dim wsDestination As Worksheet: Set wsDestination = Sheets("test")
LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
ws.Range("A1:N" & LastRow).AutoFilter Field:=1, Criteria1:=Worksheets("test").Cells(1, 26).Value
ws.Range("f2:f" & LastRow).SpecialCells(xlCellTypeVisible).Copy Range("C6")
DestinationRow = wsDestination.Cells(wsDestination.Rows.Count, "C").End(xlUp).Row + 1
wsDestination.Range("C" & DestinationRow).PasteSpecial xlPasteValues
Application.CutCopyMode = False
ws.Range("A1:N" & LastRow).AutoFilter Field:=1
End Sub
currently the first code filters and copies table data in the parameter that I want into another worksheet, but I need a more complex version of the copy so I recorded it in macro, which is super long and looks like this:
Sub Macro8()
'
' Macro8 Macro
'
'
Sheets("INBD").Select
Range("Table1[Description]").Select
Selection.Copy
Sheets("Sheet1").Select
Range("Table19[Description]").Select
ActiveSheet.Paste
Range("D18").Select
Sheets("INBD").Select
Range("Table1[Invoice Date]").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheet1").Select
Range("Table19[Invoice '#]").Select
ActiveSheet.Paste
Sheets("INBD").Select
Range("Table1[Invoice '#]").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheet1").Select
Range("Table19[Invoice '#]").Select
Selection.PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:= _
xlNone, SkipBlanks:=False, Transpose:=False
Sheets("INBD").Select
Range("Table1[HS Code]").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheet1").Select
Range("Table19[HS Code]").Select
Selection.PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:= _
xlNone, SkipBlanks:=False, Transpose:=False
Sheets("INBD").Select
Range("Table1[Unit]").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheet1").Select
Range("Table19[M. Unit]").Select
Selection.PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:= _
xlNone, SkipBlanks:=False, Transpose:=False
Range("Table19[Description]").Select
Application.CutCopyMode = False
Selection.Copy
Range("E13").Select
ActiveSheet.Paste
Sheets("INBD").Select
Range("Table1[QTY]").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheet1").Select
Range("Table19[QTY]").Select
Selection.PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:= _
xlNone, SkipBlanks:=False, Transpose:=False
Sheets("INBD").Select
Range("Table1[Unit Price]").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheet1").Select
Range("Table19[Unit Price]").Select
ActiveSheet.Paste
Sheets("INBD").Select
Range("Table1[Curr.]").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheet1").Select
Range("Table19[Curr]").Select
ActiveSheet.Paste
Selection.PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:= _
xlNone, SkipBlanks:=False, Transpose:=False
Rows("13:22").Select
Rows("13:22").EntireRow.AutoFit
Selection.RowHeight = 30
Application.CutCopyMode = False
With Selection
.WrapText = True
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
End With
What this does is that it copies values into a table, into specific columns, below the table I wrote in a bunch of stuff and made the color of the font white, so that when it copies, the table moves the cells down hence not altering anything below the table and leaves some space in between. After this I'm going to record a macro which deletes all rows in the table and any other data in the table to clear the document for a new entry.
One solution to combine two Macros would be just to type everything from the second Macro between the first and last line and paste in where you need its execution in the first code.
The other solution would be to "Call" the second Macro from the first Code by simply typing
Call Macro8
In your example :
Sub foo()
Dim ws As Worksheet: Set ws = Sheets("inbd")
Dim wsDestination As Worksheet: Set wsDestination = Sheets("test")
LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
ws.Range("A1:N" & LastRow).AutoFilter Field:=1, Criteria1:=Worksheets("test").Cells(1, 26).Value
ws.Range("f2:f" & LastRow).SpecialCells(xlCellTypeVisible).Copy Range("C6")
DestinationRow = wsDestination.Cells(wsDestination.Rows.Count, "C").End(xlUp).Row + 1
wsDestination.Range("C" & DestinationRow).PasteSpecial xlPasteValues
Application.CutCopyMode = False
ws.Range("A1:N" & LastRow).AutoFilter Field:=1
Call Macro8 ' Or Copy Paste the whole other code here
End Sub
I still strongly advise to follow the links from the comments of Foxfire And Burns And Burns about How to avoid using Select in Excel VBA.
Application.run ("macro8") <-is what I needed, I appreciate the advice though, I don't really have any knowledge in coding, but I will try to avoid using select if i can.

If file is not open go to next

From multiple workbooks I copy info into one Workbook. This works like a charm. I just got informed that in a few weeks I'll have to add another file to copy data from. I wanted to get the Macro going now but if I don't have the new workbook open the macro gets stuck. I have tried a few different ways but I don't get it to work.
I have the same code going with the other 3 workbooks, so when this comes I want the macro to skip it if Workbook is not open.
Any suggestions?
Windows("filename.xlsx").Activate
Range(Range("A2:K2"), Range("A2:K2").End(xlDown)).Copy
Workbooks("Masterfile.xlsm").Sheets("Electra").Activate
Range("A2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
This code will step through the workbooks that you have open and check against a list of file names that you need.
There's a couple of problems that could occur:
Your workbook must have a sheet called Sheet1 as the code doesn't check for this.
If you have a file called book1.xlsm and 1book1.xlsm. book1.xlsm occurs in both.
Finding the last cell in columns A:K could be improved. Currently it will go from A2 to the last row containing data in column K.
All information will be pasted starting at cell A2. You need code to find the last row on the Electra sheet as well.
Sub Test()
Dim sFileNames As String
Dim wrkBk As Workbook
sFileNames = "Somebook.xls, book1.xlsm, book2.xlsx"
For Each wrkBk In Workbooks
If InStr(UCase(sFileNames), UCase(wrkBk.Name)) > 0 Then
With wrkBk.Worksheets("Sheet1")
.Range(.Cells(2, 1), .Cells(.Rows.Count, 11).End(xlUp)).Copy
ThisWorkbook.Worksheets("Electra").Range("A2").PasteSpecial xlPasteValues
End With
End If
Next wrkBk
End Sub
Edit:
To paste to different sheets in the MasterFile one option is to use a dictionary to hold workbook & destination sheet pairings.
This code will add the file names as keys and the destination sheets as values. It then checks if the workbook name exists within the dictionary, if it does it copies the data from Sheet1 and pastes the values into relevant sheet.
Sub Test()
Dim dict As Object
Dim wrkBk As Workbook
Set dict = CreateObject("Scripting.Dictionary")
dict.CompareMode = vbTextCompare
dict.Add "Book2.xlsx", "Sheet1"
dict.Add "Book3.xlsx", "Sheet2"
For Each wrkBk In Workbooks
If dict.exists(wrkBk.Name) Then
With wrkBk.Worksheets("Sheet1")
.Range(.Cells(2, 1), .Cells(.Rows.Count, 11).End(xlUp)).Copy
ThisWorkbook.Worksheets(dict(wrkBk.Name)).Range("A2").PasteSpecial xlPasteValues
End With
End If
Next wrkBk
End Sub
Edit 2:
If the source workbooks are all closed at the start then use this code to open the relevant files, copy the info and close the file again.
Sub Test()
Dim dict As Object
Dim wrkBk As Workbook
Dim vItem As Variant
Dim sPath As String
'All workbooks to open will be in this folder.
'Remember to include the final back-slash (\).
sPath = "C:\Test\"
Set dict = CreateObject("Scripting.Dictionary")
dict.CompareMode = vbTextCompare
'If files will not all be in the same folder, then
'full file path must be included here and remove
'references to sPath variable in the code.
dict.Add "Book2.xlsx", "Sheet1"
dict.Add "Book3.xlsx", "Sheet2"
For Each vItem In dict
Set wrkBk = Workbooks.Open(sPath & vItem)
With wrkBk.Worksheets("Sheet1")
.Range(.Cells(2, 1), .Cells(.Rows.Count, 11).End(xlUp)).Copy
ThisWorkbook.Worksheets(dict(wrkBk.Name)).Range("A2").PasteSpecial xlPasteValues
End With
wrkBk.Close SaveChanges:=False
Next vItem
End Sub
This is maybee the most good looking but it actually worked, I never done Call before so I just had to try. I can run this multiple time with different books open and it don't bug out or mess things up. As faar as two test are made.
Sub Steg11()
'
' Steg1 Macro
' Macrot flyttar data från CDPPT fil med försäljningsdata,
' från fil med Electras försäljning och fil med produktdata.
' Kopierar formler, rensar försäljning till Lagerhållare
Dim MainWkbk As Workbook
Dim NextWkbk As Workbook
Set MainWkbk = ActiveWorkbook
Set NextWkbk = ActiveWorkbook
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
Application.EnableEvents = False
ActiveSheet.DisplayPageBreaks = False
' Letar in CDPPT, lägger in formler, sorterar bladet.
On Error GoTo 3
Windows("CDPPT.xlsx").Activate
Range(Range("A2"), Range("A2").End(xlToRight).End(xlDown)).Copy
Workbooks("Datamatchningsfil.xlsm").Sheets("CDPPT").Activate
Range("A2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("CDPPT").Select
Range(Range("I2"), Range("I2").End(xlToRight)).Copy
Range("H2").Select
Selection.End(xlDown).Select
ActiveCell.Offset(0, 1).Select
Range(Selection, Selection.End(xlUp)).Offset(1, 0).Select
ActiveSheet.Paste
Application.Goto Sheets("CDPPT").Range("A:M")
Selection.Sort Key1:=Range("E1"), Order1:=xlDescending, Header:=xlGuess, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
'Tar bort data där telia inte ska betala skatt
Application.Goto Sheets("CDPPT").Range("E1")
ActiveSheet.Range("$A:$M").AutoFilter Field:=5, Criteria1:="=*BRIGHTSTAR*" _
, Operator:=xlAnd
ActiveCell.Offset(1, 0).Activate
Range(Selection, Selection.End(xlDown)).Select
Selection.EntireRow.Delete
ActiveSheet.ShowAllData
ActiveWorkbook.RefreshAll
ActiveSheet.Range("$A:$M").AutoFilter Field:=5, Criteria1:="=*ELECTRA*" _
, Operator:=xlAnd
ActiveWindow.SmallScroll Down:=-6
ActiveCell.Offset(1, 0).Activate
Range(Selection, Selection.End(xlDown)).Select
Selection.EntireRow.Delete
ActiveSheet.ShowAllData
ActiveWorkbook.RefreshAll
ActiveSheet.Range("$A:$M").AutoFilter Field:=5, Criteria1:="=*Ingram*" _
, Operator:=xlAnd
ActiveWindow.SmallScroll Down:=-9
ActiveCell.Offset(1, 0).Activate
Range(Selection, Selection.End(xlDown)).Select
Selection.EntireRow.Delete
ActiveSheet.ShowAllData
ActiveWorkbook.RefreshAll
ActiveSheet.Range("$A:$M").AutoFilter Field:=3, Criteria1:="=*brev*" _
, Operator:=xlAnd
ActiveCell.Offset(1, 0).Activate
Range(Selection, Selection.End(xlDown)).Select
Selection.EntireRow.Delete
ActiveSheet.ShowAllData
ActiveWorkbook.RefreshAll
ActiveSheet.Range("$A:$M").AutoFilter Field:=3, Criteria1:="=*Konfig*" _
, Operator:=xlAnd
ActiveCell.Offset(1, 0).Activate
Range(Selection, Selection.End(xlDown)).Select
Selection.EntireRow.Delete
ActiveSheet.ShowAllData
ActiveWorkbook.RefreshAll
ActiveSheet.Range("$A:$M").AutoFilter Field:=5, Criteria1:="=*(Manuellt
inmatad)*" _
, Operator:=xlAnd
ActiveCell.Offset(1, 0).Activate
Range(Selection, Selection.End(xlDown)).Select
Selection.EntireRow.Delete
ActiveSheet.ShowAllData
ActiveWorkbook.RefreshAll
3
Call Produktdata
End Sub
Sub Produktdata()
'Letar in produktdata
On Error GoTo 4
Windows("Produktdata.xlsx").Activate
If ActiveSheet.AutoFilterMode Then Cells.AutoFilter
Range(Range("A:J"), Range("A:J").End(xlDown)).Copy
Workbooks("Datamatchningsfil.xlsm").Sheets("Produktdata").Activate
Range("A1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
4
Call Electra
End Sub
Sub Electra()
'Letar in data från Lagerhållare
On Error GoTo 5
Windows("Electra sales.xlsx").Activate
Range(Range("A2:K2"), Range("A2:K2").End(xlDown)).Copy
Workbooks("Datamatchningsfil.xlsm").Sheets("Electra").Activate
Range("A2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
5
Call TalkTelecom
End Sub
Sub TalkTelecom()
'Letar in data från Lagerhållare
On Error GoTo 6
Windows("TalkTelecom.xlsx").Activate
Range(Range("A2:K2"), Range("A2:K2").End(xlDown)).Copy
Workbooks("Datamatchningsfil.xlsm").Sheets("TalkTelecom").Activate
Range("A2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
6
Call Techdata
End Sub
Sub Techdata()
'Letar in data från Lagerhållare
On Error GoTo 7
Windows("TechData.xlsx").Activate
Range(Range("A2:K2"), Range("A2:K2").End(xlDown)).Copy
Workbooks("Datamatchningsfil.xlsm").Sheets("TechData").Activate
Range("A2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
7
Call Continue
End Sub
Sub Continue()
' Utför text till kolumn
Application.Goto Sheets("Produktdata").Range("C:C")
Columns("C:C").Select
Selection.TextToColumns Destination:=Range("C1"), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
Semicolon:=False, Comma:=False, Space:=False, Other:=False, FieldInfo _
:=Array(1, 1), TrailingMinusNumbers:=True
Application.Goto Sheets("CDPPT").Range("F:F")
Columns("F:F").Select
Selection.TextToColumns Destination:=Range("F1"), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
Semicolon:=False, Comma:=False, Space:=False, Other:=False, FieldInfo _
:=Array(1, 1), TrailingMinusNumbers:=True
Application.Calculation = xlCalculationAutomatic
ActiveWorkbook.RefreshAll
'Lägger in år och månad i blad arbetsbeskrivning
Application.Goto Sheets("CDPPT").Range("G2")
Range("G2").Copy
Sheets("Arbetsbeskrivning").Select
Range("C10").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("D10").Activate
Application.CutCopyMode = False
ActiveCell.FormulaR1C1 = "=RIGHT(RC[-1],2)"
Range("D10").Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("D10").Select
Selection.TextToColumns Destination:=Range("D10"), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
Semicolon:=False, Comma:=False, Space:=False, Other:=False, FieldInfo _
:=Array(1, 1), TrailingMinusNumbers:=True
Range("D9").Activate
ActiveCell.FormulaR1C1 = "=VLOOKUP(R[1]C,Datalistor!R[-6]C[1]:R[5]C[2],2,0)"
Range("C9").Activate
ActiveCell.FormulaR1C1 = "=Left(R[1]C,4)"
Range("C4").Activate
' kopierar data och skapar Pivotdata Telia försäljning
Sheets("CDPPT").Select
Range(Range("A2"), Range("A2").End(xlToRight).End(xlDown)).Copy
Destination:=Sheets("Matchning"). _
Range("A2")
Application.CutCopyMode = False
Sheets("CDPPT").Select
Range(Range("A2"), Range("A2").End(xlToRight).End(xlDown)).Copy
Destination:=Sheets("Pivotgrund"). _
Range("A2")
Application.CutCopyMode = False
ActiveWorkbook.RefreshAll
' Tar bort dubletter
Application.Goto Sheets("Matchning").Range("A:M")
Selection.Sort Key1:=Range("F1"), Order1:=xlDescending, Header:=xlGuess, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
Application.Goto Sheets("Matchning").Range("A1")
Range(Range("A1"), Range("A1").End(xlToRight).End(xlDown)).Select
ActiveSheet.Range("A:L").RemoveDuplicates Columns:=6, Header:= _
xlYes
ActiveWorkbook.RefreshAll
' letar in Pivotdata
Application.Goto Sheets("Matchning").Range("H2")
ActiveCell.FormulaR1C1 = "=VLOOKUP(C[-2],Pivot!C[-7]:C[-6],2,0)"
Range("H2").Select
Selection.Copy
Range(Selection, Selection.End(xlDown)).Select
ActiveSheet.Paste
ActiveWorkbook.RefreshAll
' Skapar fil med prod med saknad data
Application.Goto Sheets("Matchning").Range("A1")
Range("A1").Select
ActiveSheet.Range("$A:P").AutoFilter Field:=12, Criteria1:= _
"Check for data"
Range(Range("A1"), Range("A1").End(xlToRight).End(xlDown)).Copy
Range("A1").Select
Workbooks.Add
ActiveSheet.Paste
ActiveWorkbook.Windows(1).Caption = "Produktdata saknas"
Columns("M:P").Select
Selection.Delete Shift:=xlToLeft
Range("A1").Select
Windows("Datamatchningsfil.xlsm").Activate
Application.Goto Sheets("Matchning").Range("A1")
ActiveSheet.ShowAllData
ActiveWorkbook.RefreshAll
Application.ScreenUpdating = True
Sheets("Arbetsbeskrivning").Select
Range("C13").Select
With Selection.Font
.Color = -16776961
.TintAndShade = 0
End With
Selection.Font.Bold = True
ActiveCell.FormulaR1C1 = _
"Steg 1 klart!"
Range("C14").Select
Application.DisplayStatusBar = True
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
MsgBox ("Steg 1 klart")
End Sub

Merge 2 tables into 1. Add values next to each other, vba or formula

Looking for a way to merge 2 tables together but the volumes are in different columns.
For some reason you cant add image to posts, never mind.
Say Col A has Product, Col B has Place, Col C has Sales and Col D has Units.
Table 1 has Col A,B and C (Column D = Blank)
Table 2 has Colum C = blank
Basically, both tables have the same structure but one has units populated and sales are blank, whereas the second one has sales populated and units blank...
Now I want to create 1 table that combines this. So 1 table and it has sales and units next to each other...
The final problem, they may not add up line by line... meaning, I need if the product and place doesn't match in both tables, add to end as single row and (lets say it has units) value will appear in unit column but sales would be blank, and vice versa.
Is this possible? Happy with either a VBA or formulae solution in excel.
Thanks.
The quick and easy answer, I filtered to get unique combinations only pasted as values and then for Units I did a sumif on the product against one table to get units and then in the cell next to it (sales) I did a sumif against the second table on the product combination.
Though done in VBA
Then ran some code that checked if both units and sales was = 0 (0 in each cell next to another) then removed entirerow. If anyone wants to see the code. Let me know and I'll post.
The first step was to create a UI with all combinations and copy/paste unique values only....
Columns("A:A").Select
Application.CutCopyMode = False
Selection.insert Shift:=xlToRight
Range("A1").Select
ActiveCell.FormulaR1C1 = "UI"
Range("A2").Select
ActiveCell.FormulaR1C1 = _
"=RC[1]&"",""&RC[2]&"",""&RC[3]
&"",""&RC[4]&"",""&RC[5]&"",""&RC[6]&"",""&RC[7]&"",""&RC[8]"
Selection.AutoFill Destination:=Range("A2:A27912")
Range("A1").Select
Range(Selection, Selection.End(xlDown)).Select
Range("A1:A30000").AdvancedFilter Action:=xlFilterCopy, CopyToRange:=Range(
_
"O1"), Unique:=True
Range("O1").Select
Range(Selection, Selection.End(xlDown).Offset(-1, 0)).Select
The next thing was to sum products next to the columns and add in the "text to columns" So baically a sumif against the UI for sales and next to it for quantity...
Selection.Copy
Sheets("Next").Select
Range("A1").Select
ActiveSheet.Paste
Columns("A:A").Select
Application.CutCopyMode = False
Selection.TextToColumns Destination:=Range("A1"), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
Semicolon:=False, Comma:=True, Space:=False, Other:=False, FieldInfo _
:=Array(Array(1, 1), Array(2, 1), Array(3, 1), Array(4, 1), Array(5, 1),
Array(6, 1), _
Array(7, 1), Array(8, 1)), TrailingMinusNumbers:=True
Sheets("Other").Select
Range("B1:L1").Select
Selection.Copy
Sheets("Next").Select
Range("A1").Select
ActiveSheet.Paste
Application.CutCopyMode = False
Range("L1").Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorDark1
.TintAndShade = -0.349986266670736
.PatternTintAndShade = 0
End With
ActiveCell.FormulaR1C1 = "UI"
Range("L2").Select
Sheets("Other").Select
Range("O2").Select
Range(Selection, Selection.End(xlDown).Offset(-1, 0)).Select
Selection.Copy
Sheets("Next").Select
ActiveSheet.Paste
Range("J2").Select
Application.CutCopyMode = False
Range("J2").Select
ActiveCell.FormulaR1C1 = _
"=SUMIF('Other'!R2C1:R50000C1,RC12,'Other'!R2C[1]:R50000C[1])"
Range("J2").Select
Selection.AutoFill Destination:=Range("J2:K2"), Type:=xlFillDefault
Range("J2:K2").Select
Selection.AutoFill Destination:=Range("J2:K10000")
Range("J2:K10000").Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Columns("L:L").Select
Application.CutCopyMode = False
Selection.Delete Shift:=xlToLeft
(This section of the code isn't very neat but it does the trick...)
Next I removed the 0s if both values are 0s...
Dim VRange As Range
Set VRange = Range(ActiveSheet.Range("J1"),
ActiveSheet.Range("J1").End(xlDown))
With VRange
.AutoFilter
.AutoFilter Field:=1, Criteria1:="0"
.Resize(.Rows.Count -
1).Offset(1).SpecialCells(xlCellTypeVisible).EntireRow.Delete
.AutoFilter
End With
Sheets("Other").Select
Range("A1:I1").ClearContents
Range("A1:I1").Value = Sheets("Data").Range("C1:K1").Value
Dim URange As Range
Set URange = Range(ActiveSheet.Range("J1"),
ActiveSheet.Range("J1").End(xlDown))
With URange
.AutoFilter
.AutoFilter Field:=1, Criteria1:="0"
.Resize(.Rows.Count -
1).Offset(1).SpecialCells(xlCellTypeVisible).EntireRow.Delete
.AutoFilter
End With
Please note that I have made some changes to this so refer to your own data and match it...
Hope this is all the code for the right thing :P There is a lot more involved any I may have copied over the wrong code :(

using find function and make the resulting cell as selection in excel VBA

Hope you are enjoying good health.
I have a data recording file to keep record of POs and than it payments. I was using excel file with lots of different formulas to maximize the automation of operations. But it is getting heavier and it is impossible to work with it any more.
So I generated the idea to remove all the formulas and put it in first row only. Now i want excel to copy those formulas from that first row every time i run the command and past at the required row to update the records and immediately should it convert into value. This will keep all the data updated with automation and reduction in processing time.
The script i am using here is working but at one point i have to use find function. it should find the required value in column B of selected sheet and make selection of cell found as results. After the selection it will offset to a desired column to proceed the further steps.
Sub find()
Sample Sheets("PO").Range("a1"), Sheets("PO").Range("b:b")
End Sub
The complete script is
Sub Macro4()
'
' Update the PO/WO detail with the effect of new payment entry and alsoupdate the corresponding in payment entry
'
' Keyboard Shortcut: Ctrl+j
'
ActiveCell.Offset(0, -16).Range("A1").Select
ActiveCell.FormulaR1C1 = "*"
ActiveCell.Offset(0, 7).Range("A1").Select
Selection.Copy
ActiveSheet.Previous.Select
Range("A1").Select
ActiveSheet.Paste
End Sub
Sub find()
Sample Sheets("PO").Range("a1"), Sheets("PO").Range("b:b")
End Sub
Sub Sample(FirstRange As Range, ListRange As Range)
Dim aCell As Range, bCell As Range, oRange As Range
Set oRange = ListRange.find(what:=FirstRange.Value, LookIn:=xlValues, _
lookat:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
ActiveCell.Offset(0, 7).Range("A1").Select
ActiveCell.Offset(0, 10).Range("A1").Select
ActiveCell.FormulaR1C1 = "*"
Selection.End(xlUp).Select
Selection.End(xlToLeft).Select
ActiveCell.Offset(0, -1).Range("A1:B1").Select
ActiveCell.Activate
Selection.Copy
ActiveCell.Offset(0, 10).Range("A1").Select
Selection.End(xlDown).Select
ActiveCell.Offset(0, -10).Range("A1").Select
ActiveSheet.Paste
Application.CutCopyMode = False
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
ActiveCell.Offset(0, 10).Range("A1").Select
Application.CutCopyMode = False
Selection.ClearContents
ActiveCell.Offset(0, -10).Range("A1").Select
ActiveSheet.Next.Select
Range("A1").Select
ActiveCell.Offset(0, 16).Range("A1:B1").Select
Application.CutCopyMode = False
Selection.Copy
Range("A1").Select
Selection.End(xlDown).Select
ActiveCell.Offset(0, 16).Range("A1").Select
ActiveSheet.Paste
Application.CutCopyMode = False
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
ActiveCell.Offset(0, -16).Range("A1").Select
Application.CutCopyMode = False
Selection.ClearContents
ActiveCell.Offset(0, 17).Range("A1").Select
End Sub
Kindly suggest any resolution,
Thanks in advance
Regards
Emm, if I understand your problem correctly, all you need is a select statement.
Set oRange = ListRange.find(what:=FirstRange.Value, LookIn:=xlValues, _
lookat:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
oRange.Select
Although you don't use your oRange variable anywhere else in your code, so you might just get rid of it. Did you write this code? Do you understand it? This is by no means a clean, optimized, good, readable or fast code... But if it works for you, then never mind that.