The file I work on contains about 80,000 rows
I need to perform some basic checks and copy the results to the new sheet.
The whole thing takes about 8 minutes and I think its too long, is there any faster way?
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
lastCell = checkbook.UsedRange.Rows.Count
ReDim dataArray(2 To lastCell, 1 To 4)
For i = 2 To lastCell
dataArray(i, 1) = checkbook.Range(streetAddress & i).Value
dataArray(i, 2) = checkbook.Range(cityAddress & i).Value
dataArray(i, 3) = checkbook.Range(stateAddress & i).Value
dataArray(i, 4) = checkbook.Range(postCodeAddress & i).Value
Next I
For i = 2 To lastCell
If dataArray(i, 1) = "" Then
results.Range("A" & results.UsedRange.Rows.Count + 1 & ":" & lastCol & results.UsedRange.Rows.Count + 1).Value = checkbook.Range("A" & i & ":" & lastCol & i).Value
results.Range(commentAddress & results.UsedRange.Rows.Count).Value = "BLANK Street"
End If
If dataArray(i, 2) = "" Then
results.Range("A" & results.UsedRange.Rows.Count + 1 & ":" & lastCol & results.UsedRange.Rows.Count + 1).Value = checkbook.Range("A" & i & ":" & lastCol & i).Value
results.Range(commentAddress & results.UsedRange.Rows.Count).Value = "BLANK City"
End If
If dataArray(i, 3) = "" Then
results.Range("A" & results.UsedRange.Rows.Count + 1 & ":" & lastCol & results.UsedRange.Rows.Count + 1).Value = checkbook.Range("A" & i & ":" & lastCol & i).Value
results.Range(commentAddress & results.UsedRange.Rows.Count).Value = "BLANK State"
End If
If dataArray(i, 4) = "" Then
results.Range("A" & results.UsedRange.Rows.Count + 1 & ":" & lastCol & results.UsedRange.Rows.Count + 1).Value = checkbook.Range("A" & i & ":" & lastCol & i).Value
results.Range(commentAddress & results.UsedRange.Rows.Count).Value = "BLANK PostCode"
End If
Next i
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
I feel your pain, I had a sheet like that as well. Working cell by cell will be slow.
Try:
1) Can you try copy the whole Sheet not cell by cell so you have a backup before processing your blanks.
Some of my old code that you can use to modify, copy whole range in one go and put values in a brand new sheet:
Dim s1 As Worksheet
Dim s2 As Worksheet
Set s1 = ThisWorkbook.Sheets(strSourceSheet)
' What is range of source data
lastrow = s1.UsedRange.Rows.Count
lastcol = s1.UsedRange.Columns.Count
' copy across
s1.Range(s1.Cells(1, 1), s1.Cells(lastrow, lastcol)).Copy
' Create new empty worksheet for holding values
Set s2 = Worksheets.Add
s2.Range("A1").PasteSpecial Paste:=xlPasteValuesAndNumberFormats, SkipBlanks:=True
Application.CutCopyMode = False
' You can rename this s2 sheet
2) Then try SEARCH for your blank cells in each column and do a REPLACE. (Use Macro recorder to help get the syntax).
Some sample code below, you will need to clean this up by setting the range instead of using a select on whole column (which will add to blanks below your last row).
' go through each of your columns. Did street example here
Columns("A:A").Select
Selection.Find(What:="", After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Activate
ActiveCell.Replace What:="", Replacement:="BLANK street", LookAt:=xlWhole _
, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
Hope this helps. You seem to know how to code, but if you are stuck then let me know.
I found an answer to the problem
instead of
results.Range(commentAddress & results.UsedRange.Rows.Count)
define for e.g. j and iterate it everytime you add new value to the sheet so
results.Range("A" & k & ":" & lastCol & k ).Value = checkbook.Range("A" & i & ":" & lastCol & i).Value
results.Range(commentAddress & k).Value = "BLANK Street"
k = k + 1
from 8 mins to 5 seconds :)
As per my Knowledge, a Sheet to sheet Traverse is always a time taking process.
i would suggest to use an array to save the details of check and then use them while assigning the values.
results.Range("A" & results.UsedRange.Rows.Count + 1 & ":" & lastCol & results.UsedRange.Rows.Count + 1).Value = array(Value)
The other recommendation is to identify the blank cells during the array assignment only and store the locations in the separate array. so directly you can iterate through only blank values instead of going through all you 80,000
Related
I want to have 2 formulas with continuous looping as long as there is value in the cell next to the targeted cell, thus i need to have ifelse function but with continuous looping aswell. for now i don't know how to insert the second formula.
Range("D9").Select
Set ws = Sheets("LAP KEL BIAYA")
lastRow = ws.Range("C" & Rows.Count).End(xlUp).Row
With ws
For i = 9 To lastRow
If Len(Trim(.Range("C" & i).Value)) <> 0 Then
Function Total(Text, Number)
.Range("D" & i).Formula = "=IF(RC[-3]=""B"",IF(AND(R4C3>0,R5C3>0),SUMIFS(FBL3N!C[11],FBL3N!C[21],R4C3,FBL3N!C[22],R5C3,FBL3N!C[16],R7C4,FBL3N!C[47],RC[-1]),IF(AND(R4C3>0,R5C3=""""),SUMIFS(FBL3N!C[11],FBL3N!C[21],R4C3,FBL3N!C[16],R7C4,FBL3N!C[47],'LAP KEL BIAYA'!RC[-1]),IF(AND(R4C3=0,R5C3>0),SUMIFS(FBL3N!C[11],FBL3N!C[22],R5C3,FBL3N!C[16],R7C4,FBL3N!C[47],RC[-1]),IF(AND(R4C3=0,R5C3=0),SUMIFS(F" & _
"BL3N!C[11],FBL3N!C[16],R7C4,FBL3N!C[47],RC[-1]),"""")))))" & _
""
ElseIf Total = "False" Then
If Len(Trim(.Range("C" & i).Value)) <> 0 Then
.Range("D" & i).Formula = "=IF(AND(R4C3>0,R5C3>0,OR(R[-1]C1=""7"",R[-1]C1=""5"",R[-1]C1=""4"")),SUMIFS(FBL3N!C[11],FBL3N!C[21],R4C3,FBL3N!C[22],R5C3,FBL3N!C[16],R7C4,FBL3N!C,R[-1]C[-1]),IF(AND(R4C3>0,R5C3=0),SUMIFS(FBL3N!C[11],FBL3N!C[21],R4C3,FBL3N!C[16],R7C4,FBL3N!C,'LAP KEL BIAYA'!R[-1]C[-1]),IF(AND(R4C3=0,R5C3>0),SUMIFS(FBL3N!C[11],FBL3N!C[22],R5C3,FBL3N!C[16],R7C4,FBL3N!C,R[-1]C[-1]),IF(" & _
"AND(R4C3=0,R5C3=0),SUMIFS(FBL3N!C[11],FBL3N!C[16],R7C4,FBL3N!C,R[-1]C[-1])))))" & _
""
.Range("D" & i).Font.Color = vbRed
End If
Next i
End Function
End With
EDIT 2 - Solved by Comintern - the missed definition here -
Rows(r.Row + counter & ":" & r.Row + counter).Insert Shift:=xlDown
Should read
ws.Rows(r.Row + counter & ":" & r.Row + counter).Insert Shift:=xlDown
Original Post -
I have a tool I'm trying to make with the main primary functions -
Basic reformatting to a report
Splitting rows where a single cell has a,b,c,d into 4 rows with one value each
Row deletion or recolouring based on value in column H
File saving
It runs fine on my computer, and it runs fine on a colleagues computer when going step-by-step. However, running the code on my colleagues computer, everything runs but the output is different.
~Edit I was running step-by-step remote on a colleague's PC whilst going step-by-step on my own PC, to confirm output looked the same
I've checked around, and not able to work out what is causing this issue.
Code is run from a button, so don't believe it's an issue with activesheet. Additionally, I think I've linked every range/reference to a named worksheet. Also, I'm not hitting an error, simply it is giving a different output (specifically, more rows are deleted in the output)
Sub FDA_Macro_Clean()
Dim ws As Worksheet
Dim wb As Workbook, outputwb As Workbook
Dim lastrow As Integer, x As Integer, y As Integer
Dim rownum As Long, rownum2 As Long, string1 As Long, string2 As Long, counter As Long
Dim r As Range
Dim timeslot As String, shareddrive As String, savename As String
Application.DisplayAlerts = False 'turns off alerts
Application.ScreenUpdating = False 'turns off screen updates
'###################################### - Defines Workbook and Sheets
Set wb = Workbooks("FDA Macro Template - No GRID 11-28 2pm.xlsm")
Set ws = wb.Sheets("Import Declaration Report")
'###################################### - Delete unused cells
ws.Rows("1:56").Delete
ws.Range("A:B,Q:Q").Delete
'###################################### - defines final active row (1 of 3 times we define)
lastrow = ws.Range("a" & Rows.Count).End(xlUp).Row
'###################################### - Delete s cells which are out of scope
x = 2
Do Until x = lastrow + 1
If ws.Range("H" & x).Value = "APH - MAY PROCEED" Or ws.Range("H" & x).Value = "FDA - " Then
ws.Range("H" & x).EntireRow.Delete 'Deletes rows with above 2 criteria values
x = x - 1
End If
x = x + 1
Loop
'###################################### - Creates new rows for anything where column A/B has different values
rownum = 1
Do Until ws.Range("A" & rownum) = ""
string1 = UBound(Split(ws.Range("A" & rownum), ",")) 'counts instances of "," in Column A
string2 = UBound(Split(ws.Range("B" & rownum), ",")) 'counts instances of "," in Column B
If string1 <> string2 Or string1 = 0 Then 'if the strings are 0, skip to next item. If strings mismatch, follow error path
If string1 <> string2 Then 'If strings mismatch, follow error path
ws.Range("A" & rownum & ":N" & rownum).Interior.Color = RGB(236, 110, 212) 'ERROR PATH - Highlight Purple
ws.Range("M" & rownum).Value = ws.Range("M" & rownum).Value & "Bill/Container count mismatch" 'ERROR PATH - Add comment in column M
y = y + 1 'Value of Y is used to determine if there is an error later in the macro
End If
rownum = rownum + 1 'Next row
GoTo NextRowLoop 'increases RowNum by 1 and skips the split
End If
'Part 2 - only for lines where String1 <> 0 and String1 = String2
Set r = ws.Range("a" & rownum) 'sets r to current cell - CBL column
Dim arr As Variant
arr = Split(r, ", ") 'fills array with each bill, removing the ", "
r = arr(0) 'puts the first array value in Range 'A&r'
For counter = 1 To UBound(arr) 'adds a counter from 1 to UBound
Rows(r.Row + counter & ":" & r.Row + counter).Insert Shift:=xlDown 'inserts a new row
r.Offset(counter, 0) = arr(counter) 'puts each additional Array entry in a row added below (because location is tied to 'counter', the gap increases by one each loop)
Next counter
Erase arr 'clears the array
Set r = ws.Range("b" & rownum) 'sets range to current cell - Container column
arr = Split(r, ", ") 'fills array with each bill, removing the ", "
r = arr(0) 'puts the first array value in Range 'B&r'
For counter = 1 To UBound(arr)
r.Offset(counter, 0) = arr(counter) 'puts each additional Array entry in a row added below (because location is tied to 'counter', the gap increases by one each loop)
ws.Range(r.Offset(counter, 1), r.Offset(counter, 12)).Value = ws.Range(r.Offset(counter - 1, 1), r.Offset(counter, 12)).Value 'fills all other report data down for columns C-N
Next counter
Erase arr 'clears the array
rownum = rownum + counter 'adds the counter value to the rownum value, so we don't look in the new lines we created
NextRowLoop: 'bookmark which links to the String1 / String2 IF argument
Loop
'###################################### - redefine lastrow (2 of 3 times we define)
lastrow = ws.Range("a" & Rows.Count).End(xlUp).Row
'###################################### - Delete rows, or recolour rows based on PGA Status Description
x = 2
Do Until x = lastrow + 1
If ws.Range("H" & x).Interior.Color = RGB(236, 110, 212) Then 'FInds rows already PURPLE
GoTo NextRowLoop2 'if row colour is purple, skip
ElseIf ws.Range("H" & x).Value = "FDA - MAY PROCEED" Or ws.Range("H" & x).Value = "FDA - MAY PROCEED; APH - MAY PROCEED" Or ws.Range("H" & x).Value = "APH - MAY PROCEED; FDA - MAY PROCEED" Then
ws.Range("A" & x & ":N" & x).Interior.Color = RGB(129, 235, 111) 'sets rows with above criteria to GREEN
ElseIf Left(ws.Range("H" & x).Value, 20) = "FDA - DATA UNDER PGA" Then
ws.Range("A" & x & ":N" & x).Interior.Color = RGB(255, 255, 0) 'sets rows with above criteria to YELLOW
ElseIf ws.Range("H" & x).Value = "FDA - Hold Intact" Then
ws.Range("A" & x & ":N" & x).Interior.Color = RGB(255, 0, 0) 'sets rows with above criteria to RED
End If
NextRowLoop2:
x = x + 1
Loop
'###################################### - sorts based on colour Purple > Red > Yellow > Green
With ws.Sort
With .SortFields
.Clear
.Add(ws.Range("A2"), xlSortOnCellColor, xlAscending, , xlSortNormal).SortOnValue.Color = RGB(236, 110, 212)
.Add(ws.Range("A2"), xlSortOnCellColor, xlAscending, , xlSortNormal).SortOnValue.Color = RGB(129, 235, 111)
.Add(ws.Range("A2"), xlSortOnCellColor, xlAscending, , xlSortNormal).SortOnValue.Color = RGB(255, 255, 0)
.Add(ws.Range("A2"), xlSortOnCellColor, xlAscending, , xlSortNormal).SortOnValue.Color = RGB(255, 0, 0)
.Add Key:=ws.Range("C2"), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
End With
.SetRange ws.Range("A1").CurrentRegion
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
'###################################### - Reformatting for selected columns and autofits cells
ws.Range("C2:D" & lastrow, "I2:J" & lastrow).NumberFormat = "yyyy-mm-dd" 'sets date format in date cells
ws.Range("E2:F" & lastrow).NumberFormat = "General" 'sets general format for Entry Port and Entry Number
ws.Columns("A:N").AutoFit 'autofit columns
ws.Rows("1:" & lastrow).EntireRow.AutoFit 'autofit rows
'###################################### - Creates a new workbook and moves just the output sheet
Set outputwb = Workbooks.Add
ws.Copy Before:=outputwb.Sheets(1)
outputwb.Sheets("Sheet1").Delete
'###################################### - Error Path - cleans the Macro workbook and promts user to fix Purple rows. Exit sub without saving file (needs manual saving)
If y > 0 Then
Application.DisplayAlerts = True 'turns on alerts
Application.ScreenUpdating = True 'turns on screen updates
ws.Cells.ClearContents
ws.Cells.Interior.Color = xlNone
MsgBox "Workbook has " & y & " lines where Number of Bills in Column A does not match Number of Containers in Column B. " & vbNewLine & vbNewLine & "Rows still requiring rework are highlighted Purple, and comment added to Column M." _
& vbNewLine & vbNewLine & "All other rows have been processed" & vbNewLine & vbNewLine & "Macro will now exit. Once reworked, please manually save."
Exit Sub
End If
'###################################### - Zero Error Path - cleans the Macro workbook
ws.Cells.ClearContents
ws.Cells.Interior.Color = xlNone
'###################################### - 'Saves file based on the Time we're running it
If Time() < TimeValue("13:29:00") Then
timeslot = "(Morning)"
ElseIf Time() < TimeValue("16:19:00") Then
timeslot = "(Midday)"
Else: timeslot = "(Afternoon)"
End If
shareddrive = "X:\HD Folders\HD-FDA REPORTS\DAILY FDA SHIPMENT REPORT\"
savename = "DAILY FDA SHIPMENT REPORT " & Format(Now(), ("mm.dd.yy")) & " " & timeslot
outputwb.SaveAs shareddrive & savename & ".xlsx"
Application.DisplayAlerts = True 'turns on alerts
Application.ScreenUpdating = True 'turns on screen updates
End Sub
Anyone able to save me?
There is a particular part of my code which I cannot make work,
I'm trying to do the following command on VBA =RIGHT(LEFT(X1;Z1-2);LEN(LEFT(X1;Z1-2))-FIND(":";X1))
On cell X1, there is a text: RESULTS:NG & MODEL:IJ
My VBA code is:
LR = Cells(Rows.Count, "A").End(xlUp).Row
For i = 1 To LR
cel = "A" & i
cel2 = "Y" & i
cel3 = "Z" & i
cel4 = "X" & i
Range("M" & i).Formula = "=RIGHT(LEFT(" & cel4 & "," & cel3 & "-" & 2 & "),LEN(LEFT(" & cel4 & "," & cel3 & "-" & 2 & "))-FIND(:" & cel4 & "))"
Next i
I'm open for a better approach for this issue as well
Thanks in advance
Try writing all the formulas at once and reduce using quotes within the formula as much as possible.
Range(Cells(1, "M"), cells(lr, "M")).Formula = _
"=RIGHT(LEFT(X1, Z1-2), LEN(LEFT(X1, Z1-2))-FIND(char(58), X1))"
All range and cells reference within a sub procedure are better with a properly defined parent worksheet reference.
dim lr as long
with worksheets("sheet1")
LR = .Cells(.Rows.Count, "A").End(xlUp).Row
.Range(.Cells(1, "M"), .cells(lr, "M")).Formula = _
"=RIGHT(LEFT(X1, Z1-2), LEN(LEFT(X1, Z1-2))-FIND(char(58), X1))"
end with
I'm currently trying to create a total, min, max, and average table at the bottom of the sheet. I would also like the "table" to start two cells below the last populated cell.
I am pulling in varying amounts of data which could be a single day, or as many as 100.
Sub max()
Dim N As Long
N = Cells(Rows.COUNT, "B").End(xlUp).Row
'Cells(N + 1, "B").Formula = "=MAX(B$13:B$44" & N & ")" <-COMMENTED OUT / THIS WORKS
Cells(N + 1, "B").Formula = "=IF(COUNT(B$13:B$44)=0,"",MAX(B$13:B$44))" & N & ")"
End Sub
This is what I have so far. I'm getting a 1004 error, and realize I am not calling the variable correctly. I will also need to do this across about 200 columns. Where am I going wrong?
EDIT: Update for non-contiguous tables.
This assumes you don't have anything below or to the right of the table on the worksheet and that your table starts at B13 (headers would be row 12):
Option Explicit
Public Sub BuildStatsTable()
Dim lngMaxRow As Long
Dim lngMaxCol As Long
Dim lngCol As Long
Dim strRng As String
Dim rngLastUsed As Range
Set rngLastUsed = GetLastRange(Cells(13, 2))
lngMaxCol = rngLastUsed.Column
lngMaxRow = rngLastUsed.Row
For lngCol = 2 To lngMaxCol
strRng = "R13C" & lngCol & ":R" & lngMaxRow & "C" & lngCol
Cells(lngMaxRow + 2, lngCol).FormulaR1C1 = "=IF(COUNT(" & strRng & ")=0,"""",SUM(" & strRng & "))"
Cells(lngMaxRow + 3, lngCol).FormulaR1C1 = "=IF(COUNT(" & strRng & ")=0,"""",MIN(" & strRng & "))"
Cells(lngMaxRow + 4, lngCol).FormulaR1C1 = "=IF(COUNT(" & strRng & ")=0,"""",MAX(" & strRng & "))"
Cells(lngMaxRow + 5, lngCol).FormulaR1C1 = "=IF(COUNT(" & strRng & ")=0,"""",AVERAGE(" & strRng & "))"
Next lngCol
End Sub
Private Function GetLastRange(rngTopLeft As Range) As Range
Dim rngUsed As Range
Dim lngMaxRow As Long
Dim lngMaxCol As Long
Set rngUsed = Range(rngTopLeft, rngTopLeft.SpecialCells(xlCellTypeLastCell))
lngMaxRow = rngUsed.Find(What:="*", _
After:=rngUsed.Cells(1), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
lngMaxCol = rngUsed.Find(What:="*", _
After:=rngUsed.Cells(1), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
Set GetLastRange = Cells(lngMaxRow, lngMaxCol)
End Function
When trying to use VBA to create a formula, and in that formula you want to use quotes, you have to "double up":
Cells(N + 1, "B").Formula = "=IF(COUNT(B$13:B$44)=0,"""",MAX(B$13:B$44))" & N & ")"
You can use Chr(34) to append it to the formula.
Cells(N + 1, "B").Formula = "=IF(COUNT(B$13:B$44)=0,"& Chr(34) & Chr(34) &",MAX(B$13:B$44))" & N & ")"
I have about 70,000 rows of data and two columns (Field,Data) which repeats every 50-100 rows (Record). I would like to write something that searches for the values based on "Field Text" (I'm only interested in about 5 fields) and paste the value into a new worksheet with rows as records and columns as fields. The first field I'm searching for will need to indicate new row/record.
My first attempt at this failed, and I've found little help on the forums. Although it looks like maybe a pivot table could do this?
Visual of what I'd like to do:
Example
EDIT:
I got the result I wanted but my do until "END" isnt catching. I do have "END" in the last cell of the data. Also, I'm sure there is a more efficient way to do this, any advice? Thanks!
Sub TracePull()
Dim i As Long
Dim j As Long
i = 1
j = 1
ActiveWorkbook.Sheets("Trace").Range("A1").Select
Do Until Range("A" & i) = "END"
Do Until ActiveCell = "OTDRFilename"
i = i + 1
ActiveWorkbook.Sheets("Trace").Range("A" & i).Activate
Loop
If ActiveCell = "OTDRFilename" Then
ActiveWorkbook.Sheets("Trace").Range("B" & i).Copy
ActiveWorkbook.Sheets("Sheet1").Range("A" & j + 1).PasteSpecial Paste:=xlValue
ActiveWorkbook.Sheets("Trace").Range("A" & i).Select
i = i + 1
j = j + 1
'Else
' i = i + 1
End If
Range("A" & i).Select
Do Until ActiveCell = "OTDRSpan length"
i = i + 1
ActiveWorkbook.Sheets("Trace").Range("A" & i).Activate
Loop
If ActiveCell = "OTDRSpan length" Then
ActiveWorkbook.Sheets("Trace").Range("B" & i).Copy
ActiveWorkbook.Sheets("Sheet1").Range("B" & j).PasteSpecial Paste:=xlValue
ActiveWorkbook.Sheets("Trace").Range("A" & i).Select
i = i + 1
End If
Range("A" & i).Select
Do Until ActiveCell = "OTDRSpan loss"
i = i + 1
ActiveWorkbook.Sheets("Trace").Range("A" & i).Activate
Loop
If ActiveCell = "OTDRSpan loss" Then
ActiveWorkbook.Sheets("Trace").Range("B" & i).Copy
ActiveWorkbook.Sheets("Sheet1").Range("C" & j).PasteSpecial Paste:=xlValue
ActiveWorkbook.Sheets("Trace").Range("A" & i).Select
i = i + 1
End If
Range("A" & i).Select
Do Until ActiveCell = "OTDRAverage loss"
i = i + 1
ActiveWorkbook.Sheets("Trace").Range("A" & i).Activate
Loop
If ActiveCell = "OTDRAverage loss" Then
ActiveWorkbook.Sheets("Trace").Range("B" & i).Copy
ActiveWorkbook.Sheets("Sheet1").Range("D" & j).PasteSpecial Paste:=xlValue
ActiveWorkbook.Sheets("Trace").Range("A" & i).Select
i = i + 1
End If
Range("A" & i).Select
Do Until ActiveCell = "OTDRSpan ORL"
i = i + 1
ActiveWorkbook.Sheets("Trace").Range("A" & i).Activate
Loop
If ActiveCell = "OTDRSpan ORL" Then
ActiveWorkbook.Sheets("Trace").Range("B" & i).Copy
ActiveWorkbook.Sheets("Sheet1").Range("E" & j).PasteSpecial Paste:=xlValue
ActiveWorkbook.Sheets("Trace").Range("A" & i).Select
i = i + 1
End If
Range("A" & i).Select
Do Until ActiveCell = "OTDRWavelength"
i = i + 1
ActiveWorkbook.Sheets("Trace").Range("A" & i).Activate
Loop
If ActiveCell = "OTDRWavelength" Then
ActiveWorkbook.Sheets("Trace").Range("B" & i).Copy
ActiveWorkbook.Sheets("Sheet1").Range("F" & j).PasteSpecial Paste:=xlValue
ActiveWorkbook.Sheets("Trace").Range("A" & i).Select
i = i + 1
End If
i = i + 1
ActiveWorkbook.Sheets("Trace").Range("A" & i).Select
Range("A" & i).Select
Loop
End Sub
I think your main problem is incrementing i twice (which passes 'END' cell) at the bottom of your code.
One way to make it more readable is by using select case. Also, you can speed up the code by assigning the value directly (without copy paste) and by turning off screen updating since you have 70,000 rows. Those things will improve performance considerably.
Sub TracePull()
ScreenUpdating = False
Dim i As Long
Dim j As Long
i = 1
j = 1
ActiveWorkbook.Sheets("Trace").Range("A1").Select
Do Until Range("A" & i) = "END"
Select Case ActiveCell.Text
Case "OTDRFilename"
ActiveWorkbook.Sheets("Sheet1").Range("A" & j + 1).Value = ActiveWorkbook.Sheets("Trace").Range("B" & i).Value
Case "OTDRSpan length"
ActiveWorkbook.Sheets("Sheet1").Range("B" & j).Value = ActiveWorkbook.Sheets("Trace").Range("B" & i).Value
Case "OTDRSpan loss"
ActiveWorkbook.Sheets("Sheet1").Range("C" & j).Value = ActiveWorkbook.Sheets("Trace").Range("B" & i).Value
Case "OTDRAverage loss"
ActiveWorkbook.Sheets("Sheet1").Range("D" & j).Value = ActiveWorkbook.Sheets("Trace").Range("B" & i).Value
Case "OTDRSpan ORL"
ActiveWorkbook.Sheets("Sheet1").Range("E" & j).Value = ActiveWorkbook.Sheets("Trace").Range("B" & i).Value
Case "OTDRWavelength"
ActiveWorkbook.Sheets("Sheet1").Range("F" & j).Value = ActiveWorkbook.Sheets("Trace").Range("B" & i).Value
End Select
i = i + 1
j = j + 1
ActiveWorkbook.Sheets("Trace").Range("A" & i).Select
Loop
ScreenUpdating = True
End Sub
You might also want to consider defining the workbook and worksheet rather than relying upon activesheet. In addition, the code with break if someone forget to have 'END' entered in the last cell, so maybe just get last cell used instead of looking for 'END'
Dim wb As Workbook
Dim wskA As Worksheet
Dim wskB As Worksheet
wb = ActiveWorkbook
wskA = wb.Sheets("Trace")
wskB = wb.Sheets("Sheet1")
numofrows = wskA.Offset(wskA.Rows.Count - 1, 0).End(xlUp).Row
wskA.Range("A1").Select
Do Until i > numofrows
Select Case ActiveCell.Text
Case "OTDRFilename"
wskB.Range("A" & j + 1).Value = wskA.Range("B" & i).Value