Running Macro Crashes Excel - vba

I'm trying to run a macro but now it keeps freezing excel.
It runs with 10 cells, but when the macro is applied to almost two hundred, it freezes and crashes.
Sub eancheck()
Dim s1 As Worksheet, s2 As Worksheet
Dim Msg As String
Set s1 = Sheets("Sheet1")
Set s2 = Sheets("Sheet3")
Dim lr1 As Long, lr2 As Long
lr1 = s1.Range("A" & Rows.Count).End(xlUp).Row
lr2 = s2.Range("a" & Rows.Count).End(xlUp).Row
Dim i As Long, j As Long
Application.ScreenUpdating = False
For i = 2 To lr1
s1.Cells(i, "D").Interior.ColorIndex = 0
For j = 2 To lr2
If s2.Range("A" & j) = s1.Range("D" & i) Then
's1.Range("D" & i) = s2.Range("B" & j)
s1.Cells(i, "D").Interior.ColorIndex = 3
End If
Next j
Next i
Application.ScreenUpdating = True
End Sub
I'm having problems with other macros too, and i think is because of the size of the range. How can i fix it?
Note: The macro runs when searching 10 values in a sheet with two columns with almost 200.000 values each, but when instead of 10 is 200, crashes.

Use conditional formatting in your sheet1 with formula and apply it on range like D2:D5000 or whatever is suitable.
=COUNTIF(Sheet3!A2,D2)>0

Try Declaring all the required variables separately.
Use Application.ScreenUpdating = false in the beginning of the program.
Your first line of for loop can be outside the for loop as well.
Use Collections to make the checks.
For Example, I started with data like this on Sheet 1 Col A,
And data like this on Sheet 3 Col A.
And this is the Macro that I have,
Sub eancheck()
Application.ScreenUpdating = False
Dim s1 As Worksheet
Dim s2 As Worksheet
Dim Msg As String
Dim lr1 As Long
Dim lr2 As Long
Dim i As Long
Dim j As Long
Dim Sheet1ObjectsCol As Collection
Dim Sheet3ObjectsCol As Collection
Dim IdentifierCol As Collection
Set s1 = ThisWorkbook.Sheets("Sheet1")
Set s2 = ThisWorkbook.Sheets("Sheet3")
Set Sheet1ObjectsCol = New Collection
Set Sheet3ObjectsCol = New Collection
Set IdentifierCol = New Collection
lr1 = s1.Range("A" & Rows.Count).End(xlUp).Row
lr2 = s2.Range("a" & Rows.Count).End(xlUp).Row
s1.Range("D2" & ":" & "D" & lr1).Interior.ColorIndex = 0
'Load the collections
For i = 2 To lr1
Sheet1ObjectsCol.Add s1.Range("A" & i).Value
Next
'Load the collections
On Error Resume Next
For i = 2 To lr2
Sheet3ObjectsCol.Add s2.Range("A" & i).Value, CStr(s2.Range("A" & i).Value)
Next
'Create the Identifier Collection
For i = 1 To Sheet1ObjectsCol.Count
ColorValReq = 0
For j = 1 To Sheet3ObjectsCol.Count
If Sheet1ObjectsCol(i) = Sheet3ObjectsCol(j) Then
ColorValReq = 3
GoTo Idenitified
End If
Next
Idenitified:
IdentifierCol.Add ColorValReq
Next
For i = 1 To IdentifierCol.Count
j = i + 1
If IdentifierCol(i) = 3 then
s1.Range("D" & j).Interior.ColorIndex = IdentifierCol(i)
End if
Next
Application.ScreenUpdating = True
End Sub
And this is the output I got,

Related

count row cell and copy and paste

I using my code for working with c# based macro soft
but i want do my macro only using VBA, not using c#
is it can do it? not using point?
Data in B2~Bxxxxx
my c# program do copy B2 cell value and paste another worksheets K3 cell
run macro under code
Sub CopyRows()
Application.ScreenUpdating = False
Application.EnableEvents = False
ActiveSheet.DisplayPageBreaks = False
Dim bottomL As Long
Dim x As Long
bottomL = Sheets("Total").Range("L" & Rows.Count).End(xlUp).Row: x = 1
Dim c As Range
Dim lr As Long
lr = Cells(Rows.Count, 1).End(xlUp).Row
For Each c In Sheets("Total").Range("K1:K" & bottomL)
If c.Value = "Inside" Then
c.EntireRow.Copy Worksheets("filter").Range("A" & Rows.Count).End(xlUp).Offset(1, 0)
x = x + 1
End If
Next c
End Sub
then my c# program do select b3 and copy to otherworksheet k3 cell then run macro then loop that process and end be cell on Bxxxxx
anyone know that working only using VBA?
Thanks and Sorry for my Bad English
In VBA make the full code like this:
Function CopyRows()
Application.ScreenUpdating = False
Application.EnableEvents = False
ActiveSheet.DisplayPageBreaks = False
Dim bottomL As Long
Dim x As Long
bottomL = Sheets("Total").Range("L" & Rows.Count).End(xlUp).Row
x = 1
Dim c As Range Dim lr As Long
lr = Cells(Rows.Count, 1).End(xlUp).Row
For Each c In Sheets("Total").Range("K1:K" & bottomL)
If c.Value = "Inside" Then
c.EntireRow.Copy
Worksheets("filter").Range("A" & Rows.Count).End(xlUp).Offset(1, 0)
x = x + 1
End If
Next c
End Function
Sub Main()
Dim bottomB As Long
Dim y As Long
bottomB = Range("B" & Rows.Count).End(xlUp).Row
For y = 2 To bottomB
Range("B" & 2).Copy Worksheets("Total").Range("K3")
CopyRows
Next
End Sub
Then only run Sub Main().
Thanks Wasif Hasan
I already using like this code i made
Sub dual()
Application.ScreenUpdating = False ActiveSheet.DisplayPageBreaks = False
Dim i As Long
Dim totalRows As Long
Dim lastRow As Long
Dim Number As Long
Dim nowRows As Long
Dim bottomL As Long
Dim x As Long
Dim c As Range
Dim lr As Long
bottomL = Sheets("Total").Range("L" & Rows.Count).End(xlUp).Row: x = 1
lr = Cells(Rows.Count, 1).End(xlUp).Row
With Worksheets("List")
'for looping
totalRows = .Cells(.Rows.Count, "B").End(xlUp).Row
'index of row to add from
lastRow = totalRows + 1 '<--| start pasting values one row below the last non empty one in column "B"
'data starts at row #2
For i = 2 To totalRows
If .Cells(i, 2).Value > 0 Then
Worksheets("List").Cells(i, "B").Copy
Worksheets("Total").Range("K3").PasteSpecial Paste:=xlPasteValues
lastRow = lastRow + Number
For Each c In Sheets("Total").Range("L1:L" & bottomL)
If c.Value = "Inside" Then
c.EntireRow.Copy Worksheets("filter").Range("A" & Rows.Count).End(xlUp).Offset(1, 0)
x = x + 1
End If
Next c
End If
Next i
End With Application.ScreenUpdating = True ActiveSheet.DisplayPageBreaks = True End Sub
but its lost many data at copy&paste
so it need wait paste done
so i using other program
is it any option to make waiting paste done?
Thnaks your Answer
If it is not necessary to copy and paste than try not to use that command. It is faster to just use cell1.Value = cell2.Value.
In your case you should declare a variable to count the total amount of columns in b. Then use a loop to go through b2 up to bx.
Example:
dim i as Integer
dim j as Integer
j = 3
For i = 2 to totalCount
Worksheet.Cells(2, i).Value = Worksheet2.Cells(11, j)
j = j + 1
Next i
In the above 2 = Column B and 11 = Column K

Excel Macro doesn't copy contents of rows

I'm trying to create a macro that compares 2 columns, each one from a different file, and gets every match into a third file together with some additional cells from one of the files.
Also, in the first 2 files have some editing on them so their cells with actual data start on the 4th and 2nd row of their respective columns so i used 2 different variable so my loops would start at these cells.
The thing is, even if my macro runs without errors it doesn't copy the data to the third file.
I have the following code:
Sub Compare()
Dim w1 As Worksheet, w2 As Worksheet, w3 As Worksheet
Dim range1 As Range, range2 As Range
Set w1 = Workbooks("Worksheet_Name1").Worksheets("Sheet1")
Set w2 = Workbooks("Worksheet_Name2").Worksheets("Sheet2")
Set w3 = Workbooks("Worksheet_Name3").Worksheets("Sheet3")
Set range1 = w1.Range("E4", w1.Range("E" & Rows.Count).End(xlUp))
Set range2 = w2.Range("A2", w2.Range("A" & Rows.Count).End(xlUp))
For Each c In range2
rangeVar2 = c
If rangeVar2 > 3 Then
For Each n In range1
rangeVar1 = n
If rangeVar > 2 Then
If w1.Cells(n, "E").Value = w2.Cells(c, "A").Value Then
w3.Cells(c, "A").Value = w1.Cells(c, "E").Value
w3.Cells(c, "B").Value = w2.Cells(c, "A").Value
End If
End If
Next n
End If
Next c
End Sub
Okay, I re-wrote this for you and changed a few things. This could still be modified a bit but this should at least work for now.
The rangeVar1 and rangeVar2 were completely redundant, also preventing your code from running (I think). No need for those.
Sub ReWrite()
Dim w1 As Worksheet, w2 As Worksheet, w3 As Worksheet
Set w1 = Workbooks("Worksheet_Name1").Worksheets("Sheet1")
Set w2 = Workbooks("Worksheet_Name2").Worksheets("Sheet2")
Set w3 = Workbooks("Worksheet_Name3").Worksheets("Sheet3")
Dim lastrow1 As Long, lastrow2 As Long, i As Long, j As Long
lastrow1 = w1.Cells(w1.Rows.Count, "E").End(xlUp).Row
lastrow2 = w2.Cells(w2.Rows.Count, "A").End(xlUp).Row
For i = 4 To lastrow1
For j = 2 To lastrow2
If w1.Range("E" & i).Value = w2.Range("A" & j).Value Then
w3.Range("A" & j).Value = w1.Range("E" & i).Value
w3.Range("B" & j).Value = w2.Range("A" & j).Value
End If
Next j
Next i
End Sub

Convert headers and row level data to column level

I have very little experience working with VBA, so I'm having a hard time looking up what I am trying to do because I am having a hard time putting what I am trying to do into words.
I have been struggling to write a code to do the below task for the past few days.
Basically what I am trying to do is to convert a set of data to different format.
This what my source data looks like.
Data:
and I need it to look like this
FinalLook:
I've a already setup a code which is lengthy and incomplete.
FIRST PART
I started with retrieving a part of a data (AQ:BA) and then convert to the format in sheet2 with the below code.
Sub FirstPart()
Dim lastRow As Long
Dim Laaastrow As Long
Sheets("sheet2").Range("a2:A5000").ClearContents
lastRow = Sheets("Sheet1").Range("c" & Rows.Count).End(xlUp).Row
Sheets("Sheet2").Range("A2:A" & lastRow).Value = Sheets("Sheet1").Range("c5:c" & lastRow).Value
Sheets("Sheet2").Range("b2:l" & lastRow).Value = Sheets("Sheet1").Range("aq5:ba" & lastRow).Value
End Sub
But.. the problem i am facing with this code is that it pulls all the data, i do not want it to pull all the values, but only the ones which is not empty or 0. In other words, if AQ6:BA6 is empty, script should skip this particular row and go the next one.
SECOND PART (converting the sheet2 data to the final format)
Sub NormalizeSheet()
Dim wsSheet2 As Worksheet
Dim wsSheet4 As Worksheet
Dim strKey As String
Dim clnHeader As Collection
Dim lngColumnCounter As Long
Dim lngRowCounterSheet2 As Long
Dim lngRowCounterSheet4 As Long
Dim rngCurrent As Range
Dim varColumn As Variant
Set wsSheet2 = ThisWorkbook.Worksheets("Sheet2")
Set wsSheet4 = ThisWorkbook.Worksheets("Sheet4")
Set clnHeader = New Collection
wsSheet4.Range("c2:c5000").ClearContents
wsSheet4.Range("e2:e5000").ClearContents
wsSheet4.Range("g2:g5000").ClearContents
lngColumnCounter = 2
lngRowCounterSheet2 = 1
Set rngCurrent = wsSheet2.Cells(lngRowCounterSheet2, lngColumnCounter)
Do Until IsEmpty(rngCurrent.Value)
clnHeader.Add rngCurrent.Value, CStr(lngColumnCounter)
lngColumnCounter = lngColumnCounter + 1
Set rngCurrent = wsSheet2.Cells(lngRowCounterSheet2, lngColumnCounter)
Loop
lngRowCounterSheet2 = 2
lngRowCounterSheet4 = 1
lngColumnCounter = 1
Do While Not IsEmpty(wsSheet2.Cells(lngRowCounterSheet2, lngColumnCounter))
Set rngCurrent = wsSheet2.Cells(lngRowCounterSheet2, lngColumnCounter)
strKey = rngCurrent.Value
lngColumnCounter = 2
Do While Not IsEmpty(wsSheet2.Cells(lngRowCounterSheet2, lngColumnCounter))
Set rngCurrent = wsSheet2.Cells(lngRowCounterSheet2, lngColumnCounter)
If rngCurrent.Value = "NULL" Then
Else
wsSheet4.Range("c" & lngRowCounterSheet4).Offset(1, 0).Value = strKey
wsSheet4.Range("e" & lngRowCounterSheet4).Offset(1, 0).Value = clnHeader(CStr(lngColumnCounter))
wsSheet4.Range("g" & lngRowCounterSheet4).Offset(1, 0).Value = rngCurrent.Value
lngRowCounterSheet4 = lngRowCounterSheet4 + 1
End If
lngColumnCounter = lngColumnCounter + 1
Loop
lngRowCounterSheet2 = lngRowCounterSheet2 + 1
lngColumnCounter = 1
Loop
End Sub
I got this code from another thread posted here on stakcoverflow, i modified a bit to get this work.
The problem i am encountering here is that if Sheet2 B2 is empty, the codes doesnt check sheet C2 instead it skips the whole row, which is not right here.
I know this sounds complicated, and this approach of mine may not be even feasible.
Is there ANY OTHER WAY to do this? Is there any other way to get this in a single shot instead of breaking down the data and move each set of columns to sheet2 then to final format?
See how you get on with this. You'll have to adjust range references, and possibly sheet names
Sub x()
Dim r As Long, c As Range
With Sheet1
For r = 5 To .Range("A" & Rows.Count).End(xlUp).Row
For Each c In .Range(.Cells(r, "AQ"), .Cells(r, "BK")).SpecialCells(xlCellTypeConstants)
If c.Value > 0 Then
Sheet2.Range("A" & Rows.Count).End(xlUp)(2).Value = .Range("B1").Value
Sheet2.Range("B" & Rows.Count).End(xlUp)(2).Value = .Cells(r, 1).Value
Sheet2.Range("C" & Rows.Count).End(xlUp)(2).Value = .Cells(r, 2).Value
Sheet2.Range("D" & Rows.Count).End(xlUp)(2).Value = .Cells(3, c.Column).Value
Sheet2.Range("E" & Rows.Count).End(xlUp)(2).Value = .Cells(4, c.Column).Value
Sheet2.Range("F" & Rows.Count).End(xlUp)(2).Value = "(blank)"
Sheet2.Range("G" & Rows.Count).End(xlUp)(2).Value = c.Value
End If
Next c
Next r
End With
Sheet2.Range("A1").Resize(, 7) = Array("TOPHEADER", "HEADER1", "HEADER2", "FROM", "TO", "TYPE", "UNIT")
End Sub

VBA script to find matches between column L on sheet 1 and column A on sheet 2 then paste the row that matches on sheet 3

Dim ii As Long
Dim j As Long
Dim sheet1LastRow As Long
Dim sheet2LastRow As Long
sheet1LastRow = Worksheets("Final").Range("L" & Rows.Count).End(xlUp).Row
sheet2LastRow = Worksheets("2015new").Range("A" & Rows.Count).End(xlUp).Row
For j = 2 To sheet1LastRow
For ii = 2 To sheet2LastRow
If Worksheets("Final").Cells(j, 1).Value = Worksheets("2015new").Cells(ii, 1).Value Then
Worksheets("2015new").Rows(ii & ":" & ii).Copy Sheets("Extract").Range("A65536").End(xlUp).Offset(1)
Else
End If
Next ii
Next j
Looked around forums and came up with the codes above but it doesn't seem to work. It also buffers for a while before coming back with nothing. Any help is greatly appreciated. Some extra info, both columns consist of dates and they do not amount the same. ( meaning sheet 1 has around 100rows of dates while sheet 2 has 20krows )
just looking for speed, something like this should help a lot:
Dim chkRng As Variant, runRng As Range, outRng As Range, i As Long
chkRng = Worksheets("Final").Range("L1", Worksheets("Final").Range("L" & Rows.Count).End(xlUp)).Value
For Each runRng In Worksheets("2015new").Range("A2", Worksheets("2015new").Range("A" & Rows.Count).End(xlUp))
For i = 2 To UBound(chkRng)
If chkRng(i, 1) = runRng.Value Then
If outRng Is Nothing Then Set outRng = runRng.EntireRow Else Set outRng = Union(outRng, runRng.EntireRow)
Exit For
End If
Next
Next
If Not outRng Is Nothing Then outRng.Copy Sheets("Extract").Range("A65536").End(xlUp).Offset(1)
I have make some changes on your code, hope it help. (Not tested)
Dim ii As Long
Dim j As Long
Dim sheet1LastRow As Long
Dim sheet2LastRow As Long
sheet1LastRow = Worksheets("Final").Range("L" & Rows.Count).End(xlUp).Row
sheet2LastRow = Worksheets("2015new").Range("A" & Rows.Count).End(xlUp).Row
For j = 2 To sheet1LastRow
For ii = 2 To sheet2LastRow
If Worksheets("Final").Cells(j, 1).Value = Worksheets("2015new").Cells(ii, 1).Value Then
Worksheets("2015new").Rows(ii).Copy Sheets("Extract").Range("A65536").End(xlUp).Offset(1,0)
Else
End If
Next ii
Next j

Copy row plus next 3

I have the below code that works great. It parses through all my sheets and finds the row in column A that I want and pastes it to a specified worksheet. However, I need it to copy the specified row plus the next X number of rows. Can someone help me accomplish this?
Sub FindValues()
Dim ws As Excel.Worksheet
Dim LastRow As Long
Dim i As Integer
For Each ws In Application.ThisWorkbook.Worksheets
LastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row
i = 1
Do While i <= LastRow
If ws.Range("A" & i).Value = "OwnershipType Ownership Type" Then
ws.Rows(i).Copy Sheets("Summary").Range("A2")
i = i - 1
LastRow = LastRow - 1
End If
i = i + 1
Loop
Next
End Sub
You can amend the range of rows being copied on this line like so:
ws.Rows(i & ":" & i + 3).Copy Sheets("Summary").Range("A2")
If the match was found in row 1 for example, the code would render as ws.Rows(1:4).Copy
I have done some minor modifications. Just added (i + number of rows to be copied). Check the below code:
Used Integer copyrw in the code, you can set this integer to copy the number of rows.
Sub FindValues()
Dim ws As Excel.Worksheet
Dim LastRow As Long
Dim i As Integer
Dim copyrw as Integer
copyrw = 3
For Each ws In Application.ThisWorkbook.Worksheets
LastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row
i = 1
Do While i <= LastRow
If ws.Range("A" & i).Value = "OwnershipType Ownership Type" Then
ws.Rows(i & ":" & i + copyrw).Copy Sheets("Summary").Range("A2")
i = i - 1
LastRow = LastRow - 1
End If
i = i + 1
Loop
Next
End Sub