speed up the processing of excel vba - vba

I've created excel vba file. However, it takes very long time to run the whole file because the total of the rows is up to 270,000 lines. Does anyone know how can I speed up the running process? Any help would be much appreciated. Thanks in advance.
Sub datemodifiedFile()
Dim File1 As Object
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Set File1 = fso.getfile("C:\Users\Meg\Desktop\Master File.xlsx")
If Sheets("today").Range("B1").Value = File1.DateLastModified Then
Else
Sheets("today").Range("B1").Value = File1.DateLastModified
Dim WbB As Workbook
Set WbB = Workbooks.Open(Filename:="C:\Users\Meg\Desktop\Master File.xlsx", ReadOnly:=True)
Dim SheetB As Worksheet
Dim lastrow As Long
Set SheetB = WbB.Sheets("Sheet1")
SheetB.Select
Rows("1:1").Select
'Selection.AutoFilter
'ActiveSheet.Range("A:V").AutoFilter Field:=20, Criteria1:=""
Columns("A:V").Select
Selection.Copy
ThisWorkbook.Activate
Sheets("today").Select
Range("C1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'Columns("A:X").Select
'ActiveSheet.Range("$A$1:$X$750001").RemoveDuplicates Columns:=Array(3, 4, 6), _
Header:=xlYes
Application.CutCopyMode = False
lastrow = Sheets("today").Range("D" & Rows.Count).End(xlUp).Row
Sheets("today").Cells(lastrow, 3).EntireRow.Delete
WbB.Close False
End If
End Sub
Sub dltnew()
Dim i As Long
Dim lrow As Long
lrow = Sheets("today").Range("C" & Rows.Count).End(xlUp).Row
For i = 2 To lrow
If Sheets("today").Cells(i, 2).Value = "NEW" Then
Sheets("today").Cells(i, 2).Value = ""
Sheets("today").Cells(i, 1).Value = ""
End If
Next i
End Sub
Sub comdate()
Dim Sheet1 As Worksheet
Dim Sheet3 As Worksheet
Dim lrow As Long
Dim i As Long
Set Sheet1 = ThisWorkbook.Sheets("main")
Set Sheet3 = ThisWorkbook.Sheets("today")
Sheet3.Range("A1").Value = Date
Sheet3.Range("A1").NumberFormat = "dd/mm/yyyy"
Sheet3.Range("A1").Font.Color = Sheet3.Range("A1").Interior.Color
Sheet3.Columns("A:A").EntireColumn.Hidden = False
If Sheet1.Range("B1").Value <> Sheet3.Range("A1").Value Then
Sheet1.Range("B1").Value = Sheet3.Range("A1").Value
lrow = Sheet1.Range("C" & Rows.Count).End(xlUp).Row
For i = 2 To lrow
If Sheet1.Cells(i, 2).Value = "NEW" Then
Sheet1.Cells(i, 2).Value = ""
End If
Next i
End If
End Sub
Sub Con()
Dim LasRow As Long
Application.ScreenUpdating = False
LasRow = Sheets("today").Range("C" & Rows.Count).End(xlUp).Row
Sheets("today").Range("A2:A" & LasRow).Formula = "=C2&G2&I2"
ActiveSheet.AutoFilterMode = False
Application.ScreenUpdating = True
End Sub
Sub Compare()
Dim mrow As Range, trow As Long
With Worksheets("main")
Set mrow = .Range("A2", .Range("A" & Rows.Count).End(xlUp))
End With
trow = Worksheets("today").Range("A" & Rows.Count).End(xlUp).Row
With Worksheets("today")
For j = 2 To trow
If mrow.Find(What:=.Range("A" & j).Value, LookIn:=xlValues, LookAt:=xlWhole) Is Nothing _
Then .Range("B" & j).Value = "NEW"
Next j
End With
End Sub
Sub getnew()
Dim Sheet1 As Worksheet
Dim Sheet3 As Worksheet
Dim lastrow As Long
Dim i As Long
Dim erow As Long
Set Sheet1 = ThisWorkbook.Sheets("main")
Set Sheet3 = ThisWorkbook.Sheets("today")
lastrow = Sheet3.Range("C" & Rows.Count).End(xlUp).Row
For i = 2 To lastrow
If Sheet3.Cells(i, 2).Value = "NEW" Then
erow = Sheet1.Range("C" & Rows.Count).End(xlUp).Row + 1
Sheet3.Cells(i, 2).EntireRow.Copy Destination:=Sheet1.Range("A" & erow)
Application.CutCopyMode = False
Sheet1.Select
Range("A1:X750001").Select
Selection.Sort Key1:=Range("G2"), Order1:=xlAscending, Key2:=Range("C2") _
, Order2:=xlAscending, Header:=xlGuess, OrderCustom:=1, MatchCase:= _
False, Orientation:=xlTopToBottom
End If
Next i
End Sub
Sub hidecellvalue()
Dim Sheet1 As Worksheet
Dim lastrow As Long
Dim k As Long
Set Sheet1 = ThisWorkbook.Sheets("main")
lastrow = Sheet1.Range("B" & Rows.Count).End(xlUp).Row
For k = 2 To lastrow
If Sheet1.Cells(k, 1).Value <> "NEW" Then
Sheet1.Cells(k, 1).Font.Color = Sheet1.Cells(k, 1).Interior.Color
'Sheet1.Columns("A:A").EntireColumn.Hidden = False
End If
Next k
End Sub
Sub hideSh1column()
Dim Sheet1 As Worksheet
Set Sheet1 = ThisWorkbook.Sheets("main")
Sheet1.Columns("A:A").EntireColumn.Hidden = True
Sheet1.Columns("D:F").EntireColumn.Hidden = True
Sheet1.Columns("H:H").EntireColumn.Hidden = True
Sheet1.Columns("L:L").EntireColumn.Hidden = True
Sheet1.Columns("N:N").EntireColumn.Hidden = True
Sheet1.Columns("P:P").EntireColumn.Hidden = True
End Sub
Sub HideSheet3()
Sheets("today").Visible = xlSheetVisible
End Sub

I would start with remove as much as .activate and select you have in your code and replace it with proper sheet.cell/range selection.
Then i would add this on beggining of your code
Dim previousScreenUpdating As Boolean
previousScreenUpdating = Application.ScreenUpdating
Application.ScreenUpdating = False
Dim previousCalculation As XlCalculation
previousCalculation = Application.Calculation
Application.Calculation = xlCalculationManual
and this on the end of your code
Application.ScreenUpdating = previousScreenUpdating
Application.Calculation = previousCalculation

This should be much faster.
You should always try to do as much using arrays as possible, rather than going through your data cell-by-cell.
In addition, a dictionary-based lookup is always going to beat using Find() when you're checking things in a large loop.
Sub Compare()
Dim mrow As Range, trow As Long, arr, r As Long
Dim d As Object, rngV As Range
Dim arrV, arrN, wsT As Worksheet, wsM As Worksheet
Set d = CreateObject("Scripting.Dictionary")
Set wsM = Worksheets("Main")
Set wsT = Worksheets("today")
'get all unique values in ColA on Main
arr = wsM.Range(wsM.Range("A2"), wsM.Cells(wsM.Rows.Count, 1).End(xlUp)).Value
For r = 1 To UBound(arr, 1)
d(arr(r, 1)) = 1
Next r
Set rngV = wsT.Range(wsT.Range("A2"), wsT.Cells(wsT.Rows.Count, 1).End(xlUp))
arrV = rngV.Value 'values from colA as array
arrN = rngV.Offset(0, 1).Value 'values from colB as array
'check colA against the dictionary and update colB array as needed
For r = 1 To UBound(arrV, 1)
If Not d.exists(arrV(r, 1)) Then arrN(r, 1) = "NEW"
Next r
'repopulate ColB with updated data
rngV.Offset(0, 1).Value = arrN
End Sub

Related

Vba deleting all data

I am new to vba and have written some code to delete specific data and refresh 2 pivot tables. It works fine when I step through each sub but when I add the module to a button so everything is run with the press of the button all the data is deleted.
Below is the code I have written( might be a bit cumbersome but I am still learning). I Hope someone can help me.
Sub Deleteheader()
ActiveWindow.FreezePanes = False
Rows("1:4").Select
Selection.Delete Shift:=xlUp
End Sub
Sub DeleteColumns()
Dim wsAvlRpt As Worksheet, wsSetUp As Worksheet
Set wsAvlRpt = ActiveWorkbook.Worksheets("AvlRpt")
Set wsSetUp = ActiveWorkbook.Worksheets("SetUp")
ColTotal = wsAvlRpt.UsedRange.Column + wsAvlRpt.UsedRange.Columns.Count - 1
LastCol = Split(Cells(1, ColTotal).Address, "$")(1)
For i = 1 To ColTotal
ColumnName = wsAvlRpt.Cells(1, i)
Values = wsSetUp.Range("A" & Rows.Count).End(xlUp).Row
cntColName = Application.CountIf(wsSetUp.Range("A2:A" & Values), ColumnName)
If cntColName = 0 Then
wsAvlRpt.Columns(i).EntireColumn.Delete
i = i - 1
ColTotal = ColTotal - 1
End If
If ColTotal <= i Then
Exit For
End If
Next i
wsAvlRpt.Columns(7).EntireColumn.Insert
wsAvlRpt.Range("G1").Value = "Item Desc"
Columns("G:G").Select
Selection.NumberFormat = "General"
End Sub
Public Sub DeleteStatus()
Dim wsAvlRpt As Worksheet
Dim lngLastRow As Long
Dim rngAvl As Range
Set wsAvlRpt = ThisWorkbook.Worksheets("AvlRpt")
With wsAvlRpt
lngLastRow = .Range("C" & .Rows.Count).End(xlUp).Row
Set rngAvl = .Range("A2:J" & lngLastRow)
End With
Application.DisplayAlerts = False
With rngAvl
.AutoFilter field:=8, _
Criteria1:="Ongoing", _
Operator:=xlOr, _
Criteria2:="P.Label"
.Offset(0).Resize(.Rows.Count).SpecialCells(xlCellTypeVisible).Rows.Delete
End With
Application.DisplayAlerts = True
With wsAvlRpt
.AutoFilterMode = False
If .FilterMode = True Then
.ShowAllData
End If
End With
End Sub
Sub DeleteZeroInventory()
Dim wsAvlRpt As Worksheet, wsSetUp As Worksheet
Set wsAvlRpt = ActiveWorkbook.Worksheets("AvlRpt")
Set wsSetUp = ActiveWorkbook.Worksheets("SetUp")
cntZeroInventory = Application.CountIf(wsAvlRpt.Range("I:I"), "<=0.0")
If cntZeroInventory > 0 Then
Total = wsAvlRpt.Cells(Rows.Count, "A").End(xlUp).Row
wsAvlRpt.Range("$A1:J" & Total).AutoFilter field:=9, Criteria1:="<=0.0", _
Operator:=xlFilterValues
wsAvlRpt.Range("A2:J" & Total).Select
Selection.SpecialCells(xlCellTypeVisible).EntireRow.Delete
wsAvlRpt.ShowAllData
wsAvlRpt.Columns(10).EntireColumn.Insert
wsAvlRpt.Range("J1").Value = "Available Eaches"
End If
End Sub
Sub CalcEaches()
Dim LastRow As Long
Sheets("AvlRpt").Activate
LastRow = Range("I65536").End(xlUp).Row
Range("I2:I" & LastRow).Select
Selection.Offset(0, 1).Select
Selection.FormulaR1C1 = "= RC[-1] *12"
Selection = Selection.Value
End Sub
Sub AddItemDesc()
With Sheets("AvlRpt")
.Range("G2:G" & .Range("C" & Rows.Count).End(xlUp).Row).Formula = _
"=IF(ISERROR(VLOOKUP(C2,SetUp!I:J,2,FALSE)),0,VLOOKUP(C2,SetUp!I:J,2,FALSE))"
.Range("G2:G" & .Range("A" & Rows.Count).End(xlUp).Row).Value = _
.Range("G2:G" & .Range("A" & Rows.Count).End(xlUp).Row).Value
End With
End Sub
Sub DeleteStyles()
Dim wsAvlRpt As Worksheet, wsSetUp As Worksheet
Set wsAvlRpt = ActiveWorkbook.Worksheets("AvlRpt")
Dim AvlRpt As Range
Set AvlRpt = wsAvlRpt.Range("A1", Range("A1").End(xlDown).End(xlToRight))
AvlRpt.AutoFilter field:=3, Criteria1:=Array("7A37", "8A37", "CO07", "CO81"), _
Operator:=xlFilterValues
AvlRpt.CurrentRegion.Offset(1, 0).Select
With Selection
.SpecialCells(xlCellTypeVisible).EntireRow.Delete
If wsAvlRpt.FilterMode Then
wsAvlRpt.ShowAllData
End If
End With
End Sub
Sub ClearContents()
Worksheets("CloseoutData").Range("A2:J2000").Clear
End Sub
Sub CopyDeleteAvlRpt()
Application.DisplayAlerts = False
Sheets("AvlRpt").Range("A2:J2000").Copy _
Destination:=Sheets("CloseoutData").Range("A2:J2000")
Sheets("AvlRpt").Delete
Application.DisplayAlerts = True
End Sub
Sub RefreshPivots()
ThisWorkbook.RefreshAll
End Sub
Sub PivotCopyAdults()
Dim pt As PivotTable, lRow As Long
Dim oWS_Copy As Worksheet, oWS_Paste As Worksheet
Set oWS_Copy = Sheets("Adults")
Set oWS_Paste = Sheets.Add
ActiveSheet.Name = "CloseOuts Adults"
For Each pt In oWS_Copy.PivotTables
pt.TableRange2.Copy
lRow = oWS_Paste.Cells(Rows.Count, 1).End(xlUp).Row + 1
oWS_Paste.Range("A" & lRow).PasteSpecial Paste:=xlPasteValues
oWS_Paste.Range("A" & lRow).PasteSpecial Paste:=xlPasteFormats
Next pt
oWS_Paste.Cells.Columns.AutoFit
End Sub
Sub PivotCopyYouthLadies()
Dim pt As PivotTable, lRow As Long
Dim oWS_Copy As Worksheet, oWS_Paste As Worksheet
Set oWS_Copy = Sheets("Youth&Ladies")
Set oWS_Paste = Sheets.Add
ActiveSheet.Name = "CloseOuts Youth & Ladies"
For Each pt In oWS_Copy.PivotTables
pt.TableRange2.Copy
lRow = oWS_Paste.Cells(Rows.Count, 1).End(xlUp).Row + 1
oWS_Paste.Range("A" & lRow).PasteSpecial Paste:=xlPasteValues
oWS_Paste.Range("A" & lRow).PasteSpecial Paste:=xlPasteFormats
Next pt
oWS_Paste.Cells.Columns.AutoFit
End Sub

Generate new worksheet based on column data for LARGE spreadsheets

I have a spreadsheet with 800k rows and 150 columns. I'm attempting to create new worksheets based on the contents of a column. So, for example if column Y has many elements ("alpha", "beta", "gamma", etc.) then I'd like to create new worksheets named "alpha", "beta", "gamma" which contain only the rows from the original that have those respective letters. I've found two scripts that work for smaller spreadsheets, but due to the size of this particular spreadsheet, they don't work.
Here are the two scripts that I have tried:
Sub parse_data()
Dim lr As Long
Dim ws As Worksheet
Dim vcol, i As Integer
Dim icol As Long
Dim myarr As Variant
Dim title As String
Dim titlerow As Integer
vcol = 1
Set ws = Sheets("Sheet1")
lr = ws.Cells(ws.Rows.Count, vcol).End(xlUp).Row
title = "A1:C1"
titlerow = ws.Range(title).Cells(1).Row
icol = ws.Columns.Count
ws.Cells(1, icol) = "Unique"
For i = 2 To lr
On Error Resume Next
If ws.Cells(i, vcol) <> "" And Application.WorksheetFunction.Match(ws.Cells(i, vcol), ws.Columns(icol), 0) = 0 Then
ws.Cells(ws.Rows.Count, icol).End(xlUp).Offset(1) = ws.Cells(i, vcol)
End If
Next
myarr = Application.WorksheetFunction.Transpose(ws.Columns(icol).SpecialCells(xlCellTypeConstants))
ws.Columns(icol).Clear
For i = 2 To UBound(myarr)
ws.Range(title).AutoFilter field:=vcol, Criteria1:=myarr(i) & ""
If Not Evaluate("=ISREF('" & myarr(i) & "'!A1)") Then
Sheets.Add(after:=Worksheets(Worksheets.Count)).Name = myarr(i) & ""
Else
Sheets(myarr(i) & "").Move after:=Worksheets(Worksheets.Count)
End If
ws.Range("A" & titlerow & ":A" & lr).EntireRow.Copy Sheets(myarr(i) & "").Range("A1")
Sheets(myarr(i) & "").Columns.AutoFit
Next
ws.AutoFilterMode = False
ws.Activate
End Sub
this returns "overflow"
the other code that I have tried:
Sub columntosheets()
Const sname As String = "VOTERFILE_WITHABSENTEEINFORMATI" 'change to whatever starting sheet
Const s As String = "O" 'change to whatever criterion column
Dim d As Object, a, cc&
Dim p&, i&, rws&, cls&
Set d = CreateObject("scripting.dictionary")
With Sheets(sname)
rws = .Cells.Find("*", , , , xlByRows, xlPrevious).Row
cls = .Cells.Find("*", , , , xlByColumns, xlPrevious).Column
cc = .Columns(s).Column
End With
For Each sh In Worksheets
d(sh.Name) = 1
Next sh
Application.ScreenUpdating = False
With Sheets.Add(after:=Sheets(sname))
Sheets(sname).Cells(1).Resize(rws, cls).Copy .Cells(1)
.Cells(1).Resize(rws, cls).Sort .Cells(cc), 2, Header:=xlYes
a = .Cells(cc).Resize(rws + 1, 1)
p = 2
For i = 2 To rws + 1
If a(i, 1) <> a(p, 1) Then
If d(a(p, 1)) <> 1 Then
Sheets.Add.Name = a(p, 1)
.Cells(1).Resize(, cls).Copy Cells(1)
.Cells(p, 1).Resize(i - p, cls).Copy Cells(2, 1)
End If
p = i
End If
Next i
Application.DisplayAlerts = False
.Delete
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End With
Sheets(sname).Activate
End Sub
Returns error with "excel does not have enough resources".
Is it possible to do what I want on my hardware?
You can refer to the modified subroutine in another article 'Macro for copying and pasting data to another worksheet'.
Sub CopySheet()
Dim wsAll As Worksheet
Dim wsCrit As Worksheet
Dim wsNew As Worksheet
Dim LastRow As Long
Dim LastRowCrit As Long
Dim I As Long
Set wsAll = Worksheets("All") ' change All to the name of the worksheet the existing data is on
LastRow = wsAll.Range("A" & Rows.Count).End(xlUp).Row
Set wsCrit = Worksheets.Add
' column G has the criteria eg project ref
wsAll.Range("A1:A" & LastRow).AdvancedFilter Action:=xlFilterCopy, CopyToRange:=wsCrit.Range("A1"), Unique:=True
LastRowCrit = wsCrit.Range("A" & Rows.Count).End(xlUp).Row
For I = 2 To LastRowCrit
wsAll.Copy Before:=Sheets("All")
ActiveSheet.Name = wsCrit.Range("A2")
Range("A1").CurrentRegion.AdvancedFilter Action:=xlFilterInPlace, CriteriaRange:=wsCrit.Range("A1:A2"), _
Unique:=False
wsCrit.Rows(2).Delete
Next I
Application.DisplayAlerts = False
wsCrit.Delete
Application.DisplayAlerts = True
End Sub

Filter data and copy values VBA

My code below is supposed to filter data in the wsData and then copy it into the wsTest worksheet after each other in column A. The code works except that it copies the values over each on the destination sheet rather then after each other. Any idea why?
Sub PrintReport()
Dim wbFeeReport As Workbook
Dim wsData As Worksheet
Dim wsForm As Worksheet
Dim wsTest As Worksheet
Dim FrRngCount As Range
Dim i As Integer
Dim k As Integer
Dim t As Integer
Dim s As Integer
Set wbFeeReport = Workbooks("FeExcForm.xlsm")
Set wsData = wbFeeReport.Worksheets("Data")
Set wsTest = wbFeeReport.Worksheets("Test")
wsTest.Cells.Clear
wsData.Activate
i = 1
For k = 1 To 2
With ActiveSheet
.AutoFilterMode = False
With Range("A1", Range("A" & Rows.Count).End(xlUp))
.AutoFilter 1, k
On Error Resume Next
.SpecialCells(xlCellTypeVisible).Copy Destination:=wsTest.Range("A" & i)
End With
i = wsTest.Range("A" & Rows.Count).End(xlUp)
.AutoFilterMode = False
End With
Next k
End Sub
As first point: if using a range with AutoFilter the copy will always exclude the hidden cells
With Range("A1", Range("A" & Rows.Count).End(xlUp))
.AutoFilter 1, k
.Copy wsTest.Range("A" & i)
End With
is all you need here.
Regarding your error: On Error Resume Next hides the error of i = wsTest.Range("A" & Rows.Count).End(xlUp) which would return a range rather than a numerical value.
i = wsTest.Range("A" & Rows.Count).End(xlUp).Row + 1
is your friend here :)
Everything together should look something like that:
Sub PrintReport()
Dim wbFeeReport As Workbook
Dim wsData As Worksheet
Dim wsForm As Worksheet
Dim wsTest As Worksheet
Dim FrRngCount As Range
Dim i As Integer
Dim k As Integer
Dim t As Integer
Dim s As Integer
Set wbFeeReport = Workbooks("FeExcForm.xlsm")
Set wsData = wbFeeReport.Worksheets("Data")
Set wsTest = wbFeeReport.Worksheets("Test")
wsTest.Cells.Clear
wsData.Activate
i = 1
For k = 1 To 2
With wsData
.AutoFilterMode = False
With .Range("A1", Range("A" & Rows.Count).End(xlUp))
.AutoFilter 1, k
.Copy wsTest.Range("A" & i)
End With
i = wsTest.Range("A" & Rows.Count).End(xlUp).Row + 1
.AutoFilterMode = False
End With
Next k
End Sub
EDIT: For excluding headers just change:
.Copy wsTest.Range("A" & i)
to:
If i = 1 Then .Copy wsTest.Range("A" & i) Else .Offset(1, 0).Copy wsTest.Range("A" & i)
and if you do not want any headers at all then directly use:
.Offset(1, 0).Copy wsTest.Range("A" & i)
But I havent tested it. Just tell me if you get any problems ;)

Can not stop the loop of importing rows from a sheet to another

I have a problem in the loop. I want to import lines that contain "X" in their first cell but :
It doesn't paste them from the first row
It pastes them too many times
Can someone help me ?
Sub refresh()
'
' refresh Macro
'
' Touche de raccourci du clavier: Ctrl+y
'
Dim LastRow As Integer, i As Integer
Dim wksSrc As Worksheet, wksDest As Worksheet
Dim lngRow As Long
Set wksSrc = ThisWorkbook.Worksheets("Scénarios de menace")
Set wksDest = ThisWorkbook.Worksheets("Analyse de risque S")
Application.Calculation = xlAutomatic
Application.DisplayAlerts = False
wksDest.Range("A6:AP1000").Delete
Application.DisplayAlerts = True
wksDest.Range("A6:AP1000").ClearContents 'Works directly, without selection
lngRow = wksDest.Cells(wksDest.Rows.Count, 2).End(xlUp).Row + 1
For i = 2 To wksSrc.Range("A" & wksSrc.Rows.Count).End(xlUp).Row
If wksSrc.Cells(i, 1) = "X" Then
wksSrc.Range(wksSrc.Cells(i, 2), wksSrc.Cells(i, 20)).Copy
wksDest.Range("B" & lngRow).PasteSpecial xlPasteValuesAndNumberFormats
Application.CutCopyMode = False
lngRow = lngRow + 1
End If
Next i
End Sub
sub refresh()
Dim LastRow As Integer, i As Integer
Dim wksSrc As Worksheet, wksDest As Worksheet
Dim lngRow As Long
Set wksSrc = ThisWorkbook.Worksheets("Scénarios de menace")
Set wksDest = ThisWorkbook.Worksheets("Analyse de risque S")
wksDest.Range("A6:AP1000").Delete
wksDest.Range("A6:AP1000").ClearContents 'Works directly, without selection
lngRow = 6
LastRow = wksSrc.Range("A" & wksSrc.Rows.Count).End(xlUp).Row
For i = 2 To LastRow
If wksSrc.Cells(i, 1) = "X" Then
wksSrc.Range(wksSrc.Cells(i, 2), wksSrc.Cells(i, 20)).Copy
wksDest.Range("B" & lngRow).PasteSpecial xlPasteValuesAndNumberFormats
Application.CutCopyMode = False
lngRow = lngRow + 1
End If
Next i
end sub
This version is optimized (not using a For loop)
Option Explicit
Public Sub refreshAnalyse()
Dim ws1 As Worksheet, ws2 As Worksheet, lr1 As Long
Set ws1 = ThisWorkbook.Worksheets("Scénarios de menace")
Set ws2 = ThisWorkbook.Worksheets("Analyse de risque S")
ws2.Range("B6:AP" & ws2.Cells(ws2.Rows.Count, 2).End(xlUp).Row).Clear
lr1 = ws1.Cells(ws1.Rows.Count, 2).End(xlUp).Row
Application.ScreenUpdating = False
ws1.Range("A1:A" & lr1).AutoFilter Field:=1, Criteria1:="x"
ws1.Range("B2:AP" & lr1).SpecialCells(xlCellTypeVisible).Copy
ws2.Range("B6").PasteSpecial Paste:=xlPasteValuesAndNumberFormats
ws1.Range("A6:A" & lr1).AutoFilter
ws2.Activate: ws2.Cells(1, 1).Activate
Application.ScreenUpdating = True
End Sub

Error in the loop

i have an error in the loop FOR. I don't understand why.My purpose is to activate the option "automatic calculation" then delete all old rows and finally add new ones.
Sub refresh()
'
' refresh Macro
'
' Touche de raccourci du clavier: Ctrl+y
'
Dim LastRow As Integer, i As Integer
Application.Calculation = xlAutomatic
Range("A6:AP1000").Select
Application.DisplayAlerts = False
Selection.Delete
Application.DisplayAlerts = True
Range("A6:AP1000").Select
Selection.ClearContents
Sheets("PTR").Range(“A” & Rows.Count).Select
For i = 2 To Sheets("PTR").Range(“A” & Rows.Count).End(xlUp).Row
If Cells(i, 1) = "X" Then
Range(Cells(i, 1), Cells(i, 20)).Select
Selection.Copy
Sheets("Analyse de risque").Range("B" & Rows.Count).PasteSpecial xlPasteValuesAndNumberFormats
Application.CutCopyMode = False
End If
Next i
End Sub
Dim LastRow1 As Long
Dim LastRow2 As Long
Dim i As Integer
Dim WS1 As Worksheet
Dim WS2 As Worksheet
Set WS1 = Worksheets("PTR")
LastRow1 = WS1.Cells(1048576, 1).End(xlUp).Row ' COLUMN 1 ?????????
Set WS2 = Worksheets("Analyse de risque")
LastRow2 = WS2.Cells(1048576, 1).End(xlUp).Row ' COLUMN 1 ?????
For i = 2 To LastRow1
If Cells(i, 1) = "X" Then
Range(Cells(i, 1), Cells(i, 20)).Copy
WS2.Cells(LastRow2, 1).PasteSpecial xlPasteValuesAndNumberFormats
Application.CutCopyMode = False
LastRow2 = LastRow2 + 1
End If
Next i