Filter images in Excel VBA - excel

I am writing VBA code to filter images. The goal is to write a macro to lock in the photos so they do not move when I need to filter the other columns. This is the code that I have so far. I need help doing this in VBA. Thanks.
Sub getpic()
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.EnableAnimations = False
Dim url_column As Range
Dim image_column As Range
Dim rngColSelect As String
rngColSelect = ActiveCell.Column
Set url_column = Worksheets(1).UsedRange.Columns("A")
Set image_column = Worksheets(1).UsedRange.Columns(Col_Letter(ActiveCell.Column))
Dim pic As Shape
Dim i As Long
For i = 1 To url_column.Cells.Count
If Not IsError(Range(Cells(i, ActiveCell.Column), Cells(i, ActiveCell.Column))) Then
If Left(Range(Cells(i, ActiveCell.Column), Cells(i, ActiveCell.Column)), 4) = "http" Then
Range(Cells(i, ActiveCell.Column), Cells(i, ActiveCell.Column)).Select
Set pic = ActiveSheet.Shapes.AddPicture(Range(Cells(i, ActiveCell.Column), Cells(i, ActiveCell.Column)).Value _
, msoFalse, msoTrue, Range(Cells(i, ActiveCell.Column), Cells(i, ActiveCell.Column)).Left, Range(Cells(i, ActiveCell.Column), Cells(i, ActiveCell.Column)).Top, -1, -1)
pic.LockAspectRatio = msoTrue
pic.Height = 115
pic.Placement = xlMoveAnSize
Rows(i).RowHeight = 120
Columns(Col_Letter(ActiveCell.Column)).ColumnWidth = 50
End If
End If
Next
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.EnableAnimations = True
MsgBox "Process complete!", vbOKOnly, "Completed"
End Sub
Function Col_Letter(lngCol As Long) As String
Dim vArr
vArr = Split(Cells(1, lngCol).Address(True, False), "$")
Col_Letter = vArr(0)
End Function

Related

Excel VBA Code performance is Extremely Slow

I have wrote a code which is working like Turtle walks. I have added Application Functions to make it faster but code has decided that he has to work slowly.
Any expert help will be appreciated.
Dim LastRowColumnA As Long
Dim i As Long
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
LastRowColumnA = Sheet1.Cells(Rows.Count, 1).End(xlUp).Row
For i = 11 To LastRowColumnA
If Sheet1.Cells(i, 1).Value <> "" Then
Cells(i, 7) = Evaluate("=INDEX(Table1!$A$1:$DP$27,MATCH($G$9&$E$4,Table1!$E:$E&Table1!$F:$F,0),MATCH(A" & i & ",Table1!$6:$6,0))")
Cells(i, 8) = Evaluate("=INDEX(Table1!$A$1:$DP$27,MATCH($H$9&$E$4,Table1!$E:$E&Table1!$F:$F,0),MATCH(A" & i & ",Table1!$6:$6,0))")
Cells(i, 9) = Evaluate("=INDEX(Table1!$A$1:$DP$27,MATCH($I$9&$E$4,Table1!$E:$E&Table1!$F:$F,0),MATCH(A" & i & ",Table1!$6:$6,0))")
Cells(i, 10) = Evaluate("=INDEX(Table1!$A$1:$DP$27,MATCH($J$9&$E$4,Table1!$E:$E&Table1!$F:$F,0),MATCH(A" & i & ",Table1!$6:$6,0))")
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End If
Next
second approach.
Dim LastRowColumnA As Long
LastRowColumnA = Sheet1.Cells(Rows.Count, 4).End(xlUp).Row
Sheet1.Range("G10").FormulaArray = _
"=IFERROR(INDEX(Table1!R1C1:R27C120,MATCH(R9C7&R4C5,Table1!C5&Table1!C6,0),MATCH(RC[-6],Table1!R6,0)), """")"
Sheet1.Range("G10").AutoFill Destination:=Sheet1.Range("G10:G" & LastRowColumnA), Type:=xlFillDefault
Sheet1.Range("H10").FormulaArray = _
"=IFERROR(INDEX(Table1!R1C1:R27C120,MATCH(R9C8&R4C5,Table1!C5&Table1!C6,0),MATCH(RC[-7],Table1!R6,0)), """")"
Sheet1.Range("H10").AutoFill Destination:=Sheet1.Range("H10:H" & LastRowColumnA), Type:=xlFillDefault
Sheet1.Range("I10").FormulaArray = _
"=IFERROR(INDEX(Table1!R1C1:R27C120,MATCH(R9C9&R4C5,Table1!C5&Table1!C6,0),MATCH(RC[-8],Table1!R6,0)), """")"
Sheet1.Range("I10").AutoFill Destination:=Sheet1.Range("I10:I" & LastRowColumnA), Type:=xlFillDefault
Sheet1.Range("J10").FormulaArray = _
"=IFERROR(INDEX(Table1!R1C1:R27C120,MATCH(R9C9&R4C5,Table1!C5&Table1!C6,0),MATCH(RC[-9],Table1!R6,0)), """")"
Sheet1.Range("J10").AutoFill Destination:=Sheet1.Range("J10:J" & LastRowColumnA), Type:=xlFillDefault
Formulas of First Cells which has been converted to code.
=IFERROR(INDEX(Table1!$A$1:$DP$27,MATCH($G$9&$E$4,Table1!$E:$E&Table1!$F:$F,0),MATCH(A10,Table1!$6:$6,0)), "")
=IFERROR(INDEX(Table1!$A$1:$DP$27,MATCH($H$9&$E$4,Table1!$E:$E&Table1!$F:$F,0),MATCH(A10,Table1!$6:$6,0)), "")
=IFERROR(INDEX(Table1!$A$1:$DP$27,MATCH($I$9&$E$4,Table1!$E:$E&Table1!$F:$F,0),MATCH(A10,Table1!$6:$6,0)), "")
=IFERROR(INDEX(Table1!$A$1:$DP$27,MATCH($J$9&$E$4,Table1!$E:$E&Table1!$F:$F,0),MATCH(A10,Table1!$6:$6,0)), "")
as per my comment:
Find the rows outside the loop as they will all be the same, then just find the column in the loop. It will cut down on the number of calc.
Dim LastRowColumnA As Long
Dim i As Long
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
With Sheet1
LastRowColumnA = Sheet1.Cells(Rows.Count, 1).End(xlUp).Row
Dim gRow As Variant
gRow = .Evaluate("MATCH($G$9&$E$4,Table1!$E1:$E27&Table1!$F1:$F27,0)")
Dim hRow As Variant
hRow = .Evaluate("MATCH($H$9&$E$4,Table1!$E1:$E27&Table1!$F1:$F27,0)")
Dim iRow As Variant
iRow = .Evaluate("MATCH($I$9&$E$4,Table1!$E1:$E27&Table1!$F1:$F27,0)")
Dim jRow As Variant
jRow = .Evaluate("MATCH($J$9&$E$4,Table1!$E1:$E27&Table1!$F1:$F27,0)")
For i = 11 To LastRowColumnA
If Sheet1.Cells(i, 1).Value <> "" And Not IsError(gRow) And Not IsError(hRow) And Not IsError(iRow) And Not IsError(jRow) Then
Dim clm As Variant
clm = Application.Match(.Range("A" & i), Worksheets("Table1").Range("6:6"), 0)
If Not IsError(clm) Then
.Cells(i, 7) = Worksheets("Table1").Cells(gRow, clm)
.Cells(i, 8) = Worksheets("Table1").Cells(hRow, clm)
.Cells(i, 9) = Worksheets("Table1").Cells(iRow, clm)
.Cells(i, 10) = Worksheets("Table1").Cells(jRow, clm)
End If
End If
Next
End With
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
If that is still too slow then one will need to use variant arrays and skip looping the ranges as this is slow.

Excel macro taking longtime

I am using the below excel which takes longtime to complete.
Usually i will have 30k records in invoice sheet and GRN sheet.
Can anyone suggest me to complete this task in faster way?
Sub CheckReturn()
Dim LastInvRow As Long
Dim LastGRNRow As Long
Dim i As Integer
Dim j As Integer
Application.Calculation = xlManual
LastInvRow = Sheets("Invoice").Cells(Rows.Count, "A").End(xlUp).Row
LastGRNRow = Sheets("GRN").Cells(Rows.Count, "A").End(xlUp).Row
For i = 4 To LastInvRow
For j = 2 To LastGRNRow
If Sheets("GRN").Cells(j, 11).Value = "Customer Return" And _
Sheets("GRN").Cells(j, 3).Value = Sheets("Invoice").Cells(i, 7).Value And _
Sheets("GRN").Cells(j, 18).Value = Sheets("Invoice").Cells(i, 19).Value Then
Sheets("GRN").Cells(j, 34).Copy
Sheets("Invoice").Cells(i, 48).PasteSpecial Paste:=xlPasteValues
Sheets("GRN").Cells(j, 35).Copy
Sheets("Invoice").Cells(i, 49).PasteSpecial Paste:=xlPasteValues
Sheets("GRN").Cells(j, 36).Copy
Sheets("Invoice").Cells(i, 50).PasteSpecial Paste:=xlPasteValues
Exit For
End If
Next j
Next i
Application.Calculation = xlAutomatic
MsgBox "Completed - " & Now()
End Sub
I suggest to do direct transfer of data from one sheet to the other and turn off some applications to make it even fater. Try this one:
Sub CheckReturn()
Dim LastInvRow As Long
Dim LastGRNRow As Long
Dim i As Integer
Dim j As Integer
'turn applications off, to make the macro go faster
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlManual
LastInvRow = Sheets("Invoice").Cells(Rows.Count, "A").End(xlUp).Row
LastGRNRow = Sheets("GRN").Cells(Rows.Count, "A").End(xlUp).Row
For i = 4 To LastInvRow
For j = 2 To LastGRNRow
If Sheets("GRN").Cells(j, 11).Value = "Customer Return" And _
Sheets("GRN").Cells(j, 3).Value = Sheets("Invoice").Cells(i, 7).Value And _
Sheets("GRN").Cells(j, 18).Value = Sheets("Invoice").Cells(i, 19).Value Then
Sheets("GRN").Cells(j, 34).Copy = Sheets("Invoice").Cells(i, 48)
Sheets("GRN").Cells(j, 35).Copy = Sheets("Invoice").Cells(i, 49)
Sheets("GRN").Cells(j, 36) = Sheets("Invoice").Cells(i, 50)
Exit For
End If
Next j
Next i
Application.Calculation = xlAutomatic
MsgBox "Completed - " & Now()
'turn applications back on..
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
This one should be a bit faster. Because you don´t get the values of a and b each time when the for j loop begins.
Sub CheckReturn()
Dim LastInvRow As Long
Dim LastGRNRow As Long
Dim i As Integer
Dim j As Integer
Application.Calculation = xlManual
LastInvRow = Sheets("Invoice").Cells(Rows.Count, "A").End(xlUp).Row
LastGRNRow = Sheets("GRN").Cells(Rows.Count, "A").End(xlUp).Row
For i = 4 To LastInvRow
a=Sheets("Invoice").Cells(i, 7).Value
b=Sheets("Invoice").Cells(i, 19).Value
c=Sheets("GRN").Cells(j, 34).Value
d=Sheets("GRN").Cells(j, 35).Value
e=Sheets("GRN").Cells(j, 36).Value
For j = 2 To LastGRNRow
If Sheets("GRN").Cells(j, 11).Value = "Customer Return" And _
Sheets("GRN").Cells(j, 3).Value = a And _
Sheets("GRN").Cells(j, 18).Value = b Then
Sheets("Invoice").Cells(i, 48).Value=c
Sheets("Invoice").Cells(i, 49).Value=d
Sheets("Invoice").Cells(i, 50).Value=e
Application.Statusbar= i*j*100/LastInvRow*LastGRNRow & "%"
Exit For
End If
Next j
Next i
Application.Calculation = xlAutomatic
MsgBox "Completed - " & Now()
End Sub
The statusbar will show you the progress of your task in %.

Copying from from one range to another ignoring blanks (Excel)

I'm trying to copy a range from one sheet to another, but ignoring blank rows, and making sure there aren't blank rows in the destination.
After looking on this site, I've successfully used the code below.
However, I want to expand this to a large data range and it seems to take an absolute age. Any ideas on a more efficient code? Slight newbie here!
Thanks!
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.EnableEvents = False
ActiveSheet.DisplayPageBreaks = False
Dim Source As Worksheet
Dim Destination As Worksheet
Dim i As Integer
Dim j As Integer
Set Source = Sheet1
Set Destination = Sheet4
j = 2
For i = 9 To 10000
If Source.Cells(i, 2).Value <> "" Then
Destination.Cells(j, 1).Value = Source.Cells(i, 1).Value
Destination.Cells(j, 2).Value = Source.Cells(i, 2).Value
Destination.Cells(j, 3).Value = Source.Cells(i, 3).Value
Destination.Cells(j, 4).Value = Source.Cells(i, 4).Value
Destination.Cells(j, 5).Value = Source.Cells(i, 5).Value
Destination.Cells(j, 6).Value = Source.Cells(i, 6).Value
Destination.Cells(j, 7).Value = Source.Cells(i, 7).Value
Destination.Cells(j, 8).Value = Source.Cells(i, 8).Value
Destination.Cells(j, 9).Value = Source.Cells(i, 9).Value
j = j + 1
End If
Next i
Application.ScreenUpdating = True
Application.EnableEvents = True
ActiveSheet.DisplayPageBreaks = True
Application.Calculation = xlCalculationAutomatic
End Sub
[Edited to add a bit of clarity]
Replace your for loop with codes below.
Method 1: union all the range you would like to copy, and paste them at once.
Dim copyRange As Range
For i = 9 To 10000
If Source.Cells(i, 2).Value <> "" Then
If copyRange Is Nothing Then
Set copyRange = Source.Range(Source.Cells(i, 1), Source.Cells(i, 9))
Else
Set copyRange = Union(copyRange, Source.Range(Source.Cells(i, 1), Source.Cells(i, 9)))
End If
End If
Next i
copyRange.Copy Destination.Cells(2, 1)
Method 2(recommended): Use an autofilter for filtering the data.
Dim sourceRng As Range
Set sourceRng = Source.Range(Source.Cells(9, 1), Source.Cells(10000, 9))
sourceRng.AutoFilter Field:=2, Criteria1:="<>"
sourceRng.Copy Destination.Cells(2, 1)
Source.AutoFilterMode = False
Looping through worksheet rows is almost the slowest way to process data blocks. The only thing slower is looping through both rows and columns.
I'm not sure how many records you have but this processed 1500 rows of dummy data in ~0.14 seconds.
Option Explicit
Sub Macro4()
Dim wsSource As Worksheet, wsDestination As Worksheet
Dim i As Long, j As Long, k As Long, arr As Variant
On Error GoTo safe_exit
appTGGL bTGGL:=False
Set wsSource = Sheet1
Set wsDestination = Sheet4
'collect values from Sheet1 into array
With wsSource
arr = .Range(.Cells(9, "A"), .Cells(.Rows.Count, "B").End(xlUp).Offset(0, 7)).Value
End With
'find first blank in column B
For j = LBound(arr, 1) To UBound(arr, 1)
If arr(j, 2) = vbNullString Then Exit For
Next j
'collect A:I where B not blank
For i = j To UBound(arr, 1)
If arr(i, 2) <> vbNullString Then
For k = 1 To 9: arr(j, k) = arr(i, k): Next k
j = j + 1
End If
Next i
'clear remaining rows
For i = j To UBound(arr, 1)
For k = 1 To 9: arr(i, k) = vbNullString: Next k
Next i
'put values sans blanks into Sheet4
With wsDestination
.Cells(2, "A").Resize(UBound(arr, 1), UBound(arr, 2)) = arr
End With
safe_exit:
appTGGL
End Sub
Sub appTGGL(Optional bTGGL As Boolean = True)
With Application
.EnableEvents = bTGGL
.ScreenUpdating = bTGGL
.DisplayAlerts = bTGGL
.Calculation = IIf(bTGGL, xlCalculationAutomatic, xlCalculationManual)
End With
Debug.Print IIf(bTGGL, "end: ", "start: ") & Timer
End Sub

Method 'Range' of object_Worksheet failed error -2147417848 (80010108)

I've googled extensively, but can't seem to find anything on my problem. I have a workbook that has various VBA intermingled with in cell formulas. As it sits now it works fine, but if I try and add or modify a simple cell reference such as "=N24" it breaks my code and throws up the error:
Run-time error '-2147417848 (80010108)': Method 'Range' of object'_Worksheet' failed
This happens whether I'm referencing a calculated cell, a user filled cell, or a blank cell.
Here's the sheet calculate code, which is the only code on this particular sheet. I know it's rudimentary, but usually simple is good. When it throws this error, it breaks at:
Sheets("CALCULATIONS").Range("N24").ClearContents
If I remove that code, then it breaks at the first IF statement line.
Private Sub Worksheet_Calculate()
Dim SIZE As String
Dim THICKNESS As Single
Dim WIDTH As Single
Dim HEIGHT As Single
Dim WALL As Single
Dim WALL1 As String
Dim OD As Single
Dim FINALROW As Integer
Dim i As Integer
Sheets("CALCULATIONS").Range("N24").ClearContents
If ThisWorkbook.Sheets("SHEET1").Range("E4") = "STRUCTURAL_I_BEAM" And ThisWorkbook.Sheets("SHEET1").Range("F4") <> 0 Then
Application.ScreenUpdating = False
Sheets("IBEAM").Range("Q2:Q100").ClearContents
SIZE = Sheets("SHEET1").Range("F4").Value
FINALROW = Sheets("IBEAM").Cells(Rows.Count, 2).End(xlUp).Row
For i = 2 To FINALROW
If Worksheets("IBEAM").Cells(i, 2) = SIZE Then
Worksheets("IBEAM").Cells(i, 8).Copy
Sheets("IBEAM").Range("Q" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
End If
Next i
Worksheets("CALCULATIONS").Range("N24").Value = Worksheets("IBEAM").Range("Q2").Value
Application.ScreenUpdating = True
End If
If ThisWorkbook.Sheets("SHEET1").Range("E4") = "STRUCTURAL_CHANNEL" And ThisWorkbook.Sheets("SHEET1").Range("F4") <> 0 Then
Application.ScreenUpdating = False
Sheets("CHANNEL").Range("Q2:Q100").ClearContents
SIZE = Sheets("SHEET1").Range("F4").Value
FINALROW = Sheets("CHANNEL").Cells(Rows.Count, 2).End(xlUp).Row
For i = 2 To FINALROW
If Worksheets("CHANNEL").Cells(i, 2) = SIZE Then
Worksheets("CHANNEL").Cells(i, 6).Copy
Sheets("CHANNEL").Range("Q" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
End If
Next i
Worksheets("CALCULATIONS").Range("N24").Value = Worksheets("CHANNEL").Range("Q2").Value
Application.ScreenUpdating = True
End If
If ThisWorkbook.Sheets("SHEET1").Range("E4") = "STRUCTURAL_ANGLE" And ThisWorkbook.Sheets("SHEET1").Range("F4") <> 0 Then
Application.ScreenUpdating = False
Sheets("ANGLE").Range("Q2:Q100").ClearContents
WIDTH = Sheets("SHEET1").Range("F4").Value
HEIGHT = Sheets("SHEET1").Range("G4").Value
THICKNESS = Sheets("SHEET1").Range("H4").Value
FINALROW = Sheets("ANGLE").Cells(Rows.Count, 3).End(xlUp).Row
For i = 2 To FINALROW
If Worksheets("ANGLE").Cells(i, 3) = WIDTH And Worksheets("ANGLE").Cells(i, 4) = HEIGHT And Worksheets("ANGLE").Cells(i, 6) = THICKNESS Then
Worksheets("ANGLE").Cells(i, 7).Copy
Sheets("ANGLE").Range("Q" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
End If
Next i
Worksheets("CALCULATIONS").Range("N24").Value = Worksheets("ANGLE").Range("Q2").Value
Application.ScreenUpdating = True
End If
If ThisWorkbook.Sheets("SHEET1").Range("E4") = "TUBE_RECTANGLE" And ThisWorkbook.Sheets("SHEET1").Range("F4") <> 0 Then
Application.ScreenUpdating = False
Sheets("RECTTUBE").Range("Q2:Q100").ClearContents
WIDTH = Sheets("SHEET1").Range("F4").Value
HEIGHT = Sheets("SHEET1").Range("G4").Value
WALL = Sheets("SHEET1").Range("H4").Value
FINALROW = Sheets("RECTTUBE").Cells(Rows.Count, 3).End(xlUp).Row
For i = 2 To FINALROW
If Worksheets("RECTTUBE").Cells(i, 3) = WIDTH And Worksheets("RECTTUBE").Cells(i, 4) = HEIGHT And Worksheets("RECTTUBE").Cells(i, 5) = WALL Then
Worksheets("RECTTUBE").Cells(i, 6).Copy
Sheets("RECTTUBE").Range("Q" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
End If
Next i
Worksheets("CALCULATIONS").Range("N24").Value = Worksheets("RECTTUBE").Range("Q2").Value
Application.ScreenUpdating = True
End If
If ThisWorkbook.Sheets("SHEET1").Range("E4") = "TUBE_SQUARE" And ThisWorkbook.Sheets("SHEET1").Range("F4") <> 0 Then
Application.ScreenUpdating = False
Sheets("SQUARETUBE").Range("Q2:Q100").ClearContents
WIDTH = Sheets("SHEET1").Range("F4").Value
WALL = Sheets("SHEET1").Range("H4").Value
FINALROW = Sheets("SQUARETUBE").Cells(Rows.Count, 3).End(xlUp).Row
For i = 2 To FINALROW
If Worksheets("SQUARETUBE").Cells(i, 3) = WIDTH And Worksheets("SQUARETUBE").Cells(i, 5) = WALL Then
Worksheets("SQUARETUBE").Cells(i, 6).Copy
Sheets("SQUARETUBE").Range("Q" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
End If
Next i
Worksheets("CALCULATIONS").Range("N24").Value = Worksheets("SQUARETUBE").Range("Q2").Value
Application.ScreenUpdating = True
End If
If ThisWorkbook.Sheets("SHEET1").Range("E4") = "TUBE_ROUND" And ThisWorkbook.Sheets("SHEET1").Range("F4") <> 0 Then
Application.ScreenUpdating = False
Sheets("ROUNDTUBE").Range("Q2:Q100").ClearContents
OD = Sheets("SHEET1").Range("F4").Value
WALL1 = Sheets("SHEET1").Range("H4").Value
FINALROW = Sheets("ROUNDTUBE").Cells(Rows.Count, 3).End(xlUp).Row
For i = 2 To FINALROW
If Worksheets("ROUNDTUBE").Cells(i, 3) = OD And Worksheets("ROUNDTUBE").Cells(i, 4) = WALL1 Then
Worksheets("ROUNDTUBE").Cells(i, 5).Copy
Sheets("ROUNDTUBE").Range("Q" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
End If
Next i
Worksheets("CALCULATIONS").Range("N24").Value = Worksheets("ROUNDTUBE").Range("Q2").Value
Application.ScreenUpdating = True
End If
If ThisWorkbook.Sheets("SHEET1").Range("E4") = "PIPE" And ThisWorkbook.Sheets("SHEET1").Range("F4") <> 0 Then
Application.ScreenUpdating = False
Sheets("PIPE").Range("Q2:Q100").ClearContents
OD = Sheets("SHEET1").Range("F4").Value
WALL1 = Sheets("SHEET1").Range("H4").Value
FINALROW = Sheets("PIPE").Cells(Rows.Count, 3).End(xlUp).Row
For i = 2 To FINALROW
If Worksheets("PIPE").Cells(i, 3) = OD And Worksheets("PIPE").Cells(i, 4) = WALL1 Then
Worksheets("PIPE").Cells(i, 5).Copy
Sheets("PIPE").Range("Q" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
End If
Next i
Worksheets("CALCULATIONS").Range("N24").Value = Worksheets("PIPE").Range("Q2").Value
Application.ScreenUpdating = True
End If
If ThisWorkbook.Sheets("SHEET1").Range("E4") = "SOLID_ROUND" And ThisWorkbook.Sheets("SHEET1").Range("F4") <> 0 Then
Application.ScreenUpdating = False
Sheets("ROUND").Range("Q2:Q100").ClearContents
OD = Sheets("SHEET1").Range("F4").Value
FINALROW = Sheets("ROUND").Cells(Rows.Count, 3).End(xlUp).Row
For i = 2 To FINALROW
If Worksheets("ROUND").Cells(i, 3) = OD Then
Worksheets("ROUND").Cells(i, 4).Copy
Sheets("ROUND").Range("Q" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
End If
Next i
Worksheets("CALCULATIONS").Range("N24").Value = Worksheets("ROUND").Range("Q2").Value
Application.ScreenUpdating = True
End If
If ThisWorkbook.Sheets("SHEET1").Range("E4") = "SOLID_FLAT" And ThisWorkbook.Sheets("SHEET1").Range("F4") <> 0 Then
Application.ScreenUpdating = False
Sheets("FLAT").Range("Q2:Q100").ClearContents
THICKNESS = Sheets("SHEET1").Range("F4").Value
WIDTH = Sheets("SHEET1").Range("G4").Value
FINALROW = Sheets("FLAT").Cells(Rows.Count, 3).End(xlUp).Row
For i = 2 To FINALROW
If Worksheets("FLAT").Cells(i, 3) = THICKNESS And Worksheets("FLAT").Cells(i, 4) = WIDTH Then
Worksheets("FLAT").Cells(i, 5).Copy
Sheets("FLAT").Range("Q" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
End If
Next i
Worksheets("CALCULATIONS").Range("N24").Value = Worksheets("FLAT").Range("Q2").Value
Application.ScreenUpdating = True
End If
If ThisWorkbook.Sheets("SHEET1").Range("E4") = "SOLID_SQUARE" And ThisWorkbook.Sheets("SHEET1").Range("F4") <> 0 Then
Application.ScreenUpdating = False
Sheets("SQUARE").Range("Q2:Q100").ClearContents
WIDTH = Sheets("SHEET1").Range("F4").Value
FINALROW = Sheets("SQUARE").Cells(Rows.Count, 3).End(xlUp).Row
For i = 2 To FINALROW
If Worksheets("SQUARE").Cells(i, 3) = WIDTH Then
Worksheets("SQUARE").Cells(i, 4).Copy
Sheets("SQUARE").Range("Q" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
End If
Next i
Worksheets("CALCULATIONS").Range("N24").Value = Worksheets("SQUARE").Range("Q2").Value
Application.ScreenUpdating = True
End If
If ThisWorkbook.Sheets("SHEET1").Range("E4") = "SOLID_HEX" And ThisWorkbook.Sheets("SHEET1").Range("F4") <> 0 Then
Application.ScreenUpdating = False
Sheets("HEX").Range("Q2:Q100").ClearContents
WIDTH = Sheets("SHEET1").Range("F4").Value
FINALROW = Sheets("HEX").Cells(Rows.Count, 3).End(xlUp).Row
For i = 2 To FINALROW
If Worksheets("HEX").Cells(i, 3) = WIDTH Then
Worksheets("HEX").Cells(i, 4).Copy
Sheets("HEX").Range("Q" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
End If
Next i
Worksheets("CALCULATIONS").Range("N24").Value = Worksheets("HEX").Range("Q2").Value
Worksheets("CALCULATIONS").Range("N25").Value = Worksheets("CALCULATIONS").Range("N8").Value / 12 * Worksheets("CALCULATIONS").Range("N24").Value
Worksheets("CALCULATIONS").Range("N26").Value = Worksheets("CALCULATIONS").Range("N25").Value - ((Worksheets("CALCULATIONS").Range("N6").Value * Worksheets("CALCULATIONS").Range("N10").Value / 12) * Worksheets("CALCULATIONS").Range("N24").Value)
Application.ScreenUpdating = True
End If
End Sub
While Excel is Busy calculating the cells, you are trying to delete/change the cell, invoking another calculation event. Hence blocking the cell/range access. Same will happen you had a mix of chart sheets with normal sheets.
Just disable the events before making any change/delete and once done re-enable events.
...............
Dim i As Integer
Application.EnableEvents = False
Sheets("CALCULATIONS").Range("N24").ClearContents
.........Your Code....
.....................
Application.ScreenUpdating = True
End If
Application.EnableEvents = True
Another alternative is to wait till CalculationState is xlDone but if you too many lengthy calculation, this might crash your application.
Of course you can not put reference on Range("N24") because you will get an infinite loop.
The first line of your code is proof for that:
Sheets("CALCULATIONS").Range("N24").ClearContents
Why, because you put reference of Range("N24") and click ENTER you get fired Change event, than your line for ClearContents erase content and after that you got calculation in your cell with this reference and here we go again fired Change Event because of that. And so on and so on (an infinite loop).
At your place I tried to do the following.
For example edit this line of code:
Sheets("CALCULATIONS").Range("N24").ClearContents
with this
If Sheets("CALCULATIONS").Range("N24") <> "" Then
Sheets("CALCULATIONS").Range("N24").ClearContents
End If
End every part of code with ClearContents edit like above example.
This would ensure the non-appearance of infinite loop.

How can I separate time from time zone and put time in format "yyyy-m hh:mm:ss"?

How can I separate time from time zone and put time in format "yyyy-m hh:mm:ss". Lookin for the column “Time”, create other two columns: “Time*” and “Time_Zone” .
I adapted this code, but some error occur and I put “On Error Resume Next”
For Each ws In Worksheets
For i = 1 To ws.Columns.Count
If ws.Cells(1, i) = "Hour" Then
Set s = ws.Cells(1, i)
LC = s.Column
ws.Columns(LC + 1).Insert
ws.Columns(LC).Copy
ws.Cells(1, LC + 1).PasteSpecial Paste:=xlPasteValues
ws.Cells(1, LC + 1).Value = "Time*"
Exit For
End If
Next i
For i = 1 To ws.Columns.Count
If ws.Cells(1, i) = "Time*" Then
ColLetr = Split(Cells(1, i).Address, "$")(1)
y = i
Exit For
End If
Next i
If ColLetr <> "" Then
lastRow = ws.Cells(Rows.Count, y).End(xlUp).Row
For Each cell In ws.Range(ColLetr & "3:" & ColLetr & lastRow)
If InStr(cell.Value, "/") <> 0 Then
cell.Value = RegexReplace(cell.Value, _
"(\d{2})\/(\d{2})\/(\d{4})", "$3-$2-$1")
End If
cell.NumberFormat = "yyyy-mm-dd hh:mm:ss;#"
If cell.Value <> "" Then
cell.Value = Left(cell.Value, 19)
End If
Next
End If
For i = 1 To ws.Columns.Count
If ws.Cells(1, i) = "Hour" Then
Set s = ws.Cells(1, i)
LC = s.Column
ws.Columns(LC + 2).Insert
ws.Columns(LC).Copy
ws.Cells(1, LC + 2).PasteSpecial Paste:=xlPasteValues
ws.Cells(1, LC + 2).Value = "Time_Zone"
Exit For
End If
Next i
For i = 1 To ws.Columns.Count
If ws.Cells(1, i) = "Time_Zone" Then
ColLetr = Split(Cells(1, i).Address, "$")(1)
y = i
Exit For
End If
Next i
If ColLetr <> "" Then
lastRow = ws.Cells(Rows.Count, y).End(xlUp).Row
For Each c In ws.Range(ColLetr & "3:" & ColLetr & lastRow)
If c.Value <> "" Then
On Error Resume Next
c.Value = Right(c.Value, Len(c.Value) - 20)
End If
Next
End If
Next
Application.ScreenUpdating = False
End Sub
Function RegexReplace(ByVal text As String, _
ByVal replace_what As String, _
ByVal replace_with As String) As String
Application.ScreenUpdating = False
Dim RE As Object
Set RE = CreateObject("vbscript.regexp")
RE.Pattern = replace_what
RE.Global = True
RegexReplace = RE.Replace(text, replace_with)
Application.ScreenUpdating = True
End Function
This code works for me:
Sub test()
Dim ws As Worksheet
Dim rngTime As Range
Dim cell As Range
Dim rngTarget As Range
Dim formatedTime As String
Application.ScreenUpdating = False
For Each ws In Worksheets
With ws
Set rngTime = .Range("1:1").Find(What:="Time", MatchCase:=False, LookAt:=xlWhole)
If Not rngTime Is Nothing Then
rngTime.Offset(, 1).Resize(, 2).EntireColumn.Insert
rngTime.Offset(, 1) = "Time*"
rngTime.Offset(, 2) = "Time_Zone"
lastrow = .Cells(.Rows.Count, rngTime.Column).End(xlUp).Row
Set rngTarget = .Range(.Cells(3, rngTime.Column + 1), .Cells(lastrow, rngTime.Column + 1))
rngTarget.NumberFormat = "yyyy-mm-dd hh:mm:ss;#"
For Each cell In rngTarget
If InStr(cell.Offset(, -1), "/") <> 0 Then
formatedTime = RegexReplace(cell.Offset(, -1), _
"(\d{2})\/(\d{2})\/(\d{4})", "$3-$2-$1")
cell = Trim(Left(formatedTime, 19))
cell.Offset(, 1) = Trim(Mid(formatedTime, 20))
End If
Next cell
End If
End With
Next ws
Application.ScreenUpdating = True
End Sub
Function RegexReplace(ByVal text As String, _
ByVal replace_what As String, _
ByVal replace_with As String) As String
Dim RE As Object
Set RE = CreateObject("vbscript.regexp")
RE.Pattern = replace_what
RE.Global = True
RegexReplace = RE.Replace(text, replace_with)
End Function
Note, that in your picture you're using Time header in column E, but in your're searching Hour column: If ws.Cells(1, i) = "Hour" Then. I use Time header in my code, you could change it in line Set rngTime = .Range("1:1").Find(What:="Time", MatchCase:=False, LookAt:=xlWhole).
Result:

Resources