I have been developing an Excel macro for my company that opens several workbooks, parses them for a specific line of information, stores that line, then once it has gone through each workbook sets the value of a horizontal selection of cells in a single workbook on one of two pages. The issue I am having is upon trying to select the second page I need to put data on to i get a runtime error 1004.
Here is the code;
Sub sortandinsert(listie As Variant)
'Takes in the data array and sorts it as it inserts it into the spreadsheet.
'Expects a 2 dimensional array.
Dim serialarray() As Variant
Dim listlen1 As Integer
Dim listlen2 As Integer
Dim listlen3 As Integer
Dim count1 As Integer
Dim count2 As Integer
Dim SSCcurrentrow As Integer
Dim DSCcurrentrow As Integer
Dim Colstart As Integer
Dim SSCcounter As Integer
Dim DSCcounter As Integer
Dim actbook As Workbook
Dim selectrange As range
Set actbook = ActiveWorkbook
SSCcounter = 0
DSCcounter = 0
Colstart = 1
SSCcurrentrow = 10
DSCcurrentrow = 10
serialarray = FindSerial(listie, serialarray)
listlen1 = findlength(serialarray)
For count = 0 To listlen1 - 1
MsgBox serialarray(count)
Next
With actbook
listlen2 = findlength(listie)
For count1 = 0 To listlen1 - 1
MsgBox "Current Serial is" & " " & serialarray(count1)
For count2 = 0 To listlen2 - 1
If contains(listie(count2), CStr(serialarray(count1))) Then
listlen3 = findlength(listie(count2))
If listie(count2)(0) = "SSC" Then
Set selectrange = Sheets("SSC").range(Cells(SSCcurrentrow + SSCcounter, Colstart), Cells(SSCcurrentrow + SSCcounter, Colstart + listlen3 - 1))
With selectrange
.Value = listie(count2)
End With
SSCcounter = SSCcounter + 1
ElseIf listie(count2)(0) = "DSC" Then
Set selectrange = Sheets("DSC").range(Cells(DSCcurrentrow + DSCcounter, Colstart), Cells(DSCcurrentrow + DSCcounter, Colstart + listlen3 - 1))
With selectrange
.Value = listie(count2)
End With
DSCcounter = DSCcounter + 1
End If
End If
Next
SSCcurrentrow = SSCcurrentrow + SSCcounter + 6
DSCcurrentrow = DSCcurrentrow + DSCcounter + 6
'SSCcounter = 0
'DSCcounter = 0
Next
End With
End Sub
The portion of the code where the error arises is;
Set selectrange = Sheets("DSC").range(Cells(DSCcurrentrow + DSCcounter, Colstart), Cells(DSCcurrentrow + DSCcounter, Colstart + listlen3 - 1))
With selectrange
.Value = listie(count2)
End With
At the beginning of the macro that I open a new workbook to put all the data into, then I open and close the workbooks containing the data, then return to the new workbook that was created. There is periodic saving happening over the course of the macro.
What can I do to fix this error?
Cells will reference the ActiveSheet in the ActiveWorkbook. Those objects might not be set, and they might not be on Sheet DSC. Try this instead:
With actbook.Sheets("DSC")
Set selectrange = range(.Cells(DSCcurrentrow + DSCcounter, Colstart), .Cells(DSCcurrentrow + DSCcounter, Colstart + listlen3 - 1))
End With
Or, a more readable version might be
Set selectrange = actbook.Sheets("DSC").Cells(DSCcurrentrow + DSCcounter, Colstart)
Set selectrange = selectrange.resize(1, listlen)
Related
Background: I have already used the 'conditional' formatting to highlight the 10 lowest values in each row in light red.
Now, I am trying to compose a code that searches each row for the red marked cells and copies their name from the header row to a new sheet.
What I am aiming for is the following: a code that searches each row for the cells in red and that copies the name (in header) to the same row in another sheet (=result sheet). This should result in a result sheet with 11 columns: first column being the dates and the following 10 columns in that row being the names of the lowest values for that date.
This is the code that I have so far but it does not work:
Sub CopyReds()
Dim i As Long, j As Long
Dim sPrice As Worksheet
Dim sResult As Worksheet
Set sPrice = Sheets("Prices")
Set sResult = Sheets("Result")
i = 2
For j = 2 To 217
Do Until i = 1086
If sPrice.Cells(j, i).Offset(j, 0).Interior.Color = 13551615 Then
sPrice.Cells(j, i).Copy Destination:=sResult.Cells(2, 2).Offset(j, 1)
End If
Loop
Next j
End Sub
Update: screenshot worksheet
Update 2: Screenshot result sample
I think your code should look something like this:
Option Explicit
Sub CopyReds()
Dim sPrice As Worksheet: Set sPrice = Sheets("Prices")
Dim sResult As Worksheet: Set sResult = Sheets("Result")
Const colPriceName As Long = 2 ' The column in which cells can be colored red and contains the names to copy
Const clrCopy As Long = 13551615 ' The color which indicates that the cell should be copied (red)
Const colResult As Long = 2 ' The column where the results should be copied
Const rowResultFirst As Long = 2 ' First row on sResult to use for output
Dim rowResult As Long: rowResult = rowResultFirst
Dim rowPrice As Long: For rowPrice = 2 To sPrice.UsedRange.Rows.Count - sPrice.UsedRange.Row + 1 ' Loop until last row
If DisplayedColor(sPrice.Cells(rowPrice, colPriceName)) = clrCopy Then
sResult.Cells(rowResult, colResult).Value = sPrice.Cells(rowPrice, colPriceName).Value
rowResult = rowResult + 1
End If
Next rowPrice
End Sub
Update: handling conditional formatting
If you use conditional formatting then VBA does not read the actual color displayed but the color which would be shown without Conditional Formatting. So you need a vehicle to determine the displayed color. I wrote this code based on this source but refactored it significantly, e.g. now it did not work in international environment and its readability was poor:
Function DisplayedColor(rngCell As Range, Optional bCellInterior As Boolean = True, Optional bReturnColorIndex As Long = False) As Long
Dim ewbTemp As Workbook: Set ewbTemp = Application.Workbooks.Add() ' Creates a new workbook, so that none of the cells of other workbooks is tampered with (not even temporarily) - this may be overkill, you may centralize this object or use existing cells
DisplayedColor = -1 ' Assume Failure and indicate Error
If 1 < rngCell.Count Then
Debug.Print "Error in DisplayedColor: rngCell contains more than 1 cell"
Exit Function
End If
Dim objTarget As Object: Set objTarget = rngCell
Dim i As Long: For i = 1 To rngCell.FormatConditions.Count
With rngCell.FormatConditions(i)
Dim bFormatConditionActive As Boolean: bFormatConditionActive = False
Dim varValue As Variant: varValue = rngCell.Value
Dim strFormula1 As String: strFormula1 = FormulaFromFormulaLocal(.Formula1, ewbTemp.Worksheets(1).Cells(1, 1))
Dim varEval1 As String: varEval1 = rngCell.Worksheet.Evaluate(strFormula1)
If .Type = xlCellValue Then
Select Case .Operator
Case xlEqual
bFormatConditionActive = varValue = varEval1
Case xlNotEqual
bFormatConditionActive = varValue <> varEval1
Case xlGreater
bFormatConditionActive = varValue > varEval1
Case xlGreaterEqual
bFormatConditionActive = varValue >= varEval1
Case xlLess
bFormatConditionActive = varValue < varEval1
Case xlLessEqual
bFormatConditionActive = varValue <= varEval1
Case xlBetween, xlNotBetween
Dim strFormula2 As String: strFormula2 = FormulaFromFormulaLocal(.Formula2, ewbTemp.Worksheets(1).Cells(1, 1))
Dim varEval2 As String: varEval2 = rngCell.Worksheet.Evaluate(strFormula2)
bFormatConditionActive = varEval1 <= varValue And varValue <= varEval2
If .Operator = xlNotBetween Then
bFormatConditionActive = Not bFormatConditionActive
End If
Case Else
Debug.Print "Error in DisplayedColor: unexpected Operator"
Exit Function
End Select
ElseIf .Type = xlExpression Then
bFormatConditionActive = varEval1
Else
Debug.Print "Error in DisplayedColor: unexpected Type"
Exit Function
End If
If bFormatConditionActive Then
Set objTarget = rngCell.FormatConditions(i)
Exit For
End If
End With
Next i
If bCellInterior Then
If bReturnColorIndex Then
DisplayedColor = objTarget.Interior.ColorIndex
Else
DisplayedColor = objTarget.Interior.Color
End If
Else
If bReturnColorIndex Then
DisplayedColor = objTarget.Font.ColorIndex
Else
DisplayedColor = objTarget.Font.Color
End If
End If
ewbTemp.Close False
End Function
Function FormulaFromFormulaLocal(strFormulaLocal As String, rngDummy As Range) As String
Dim strOldFormula As String: strOldFormula = rngDummy.Formula
rngDummy.FormulaLocal = strFormulaLocal
FormulaFromFormulaLocal = rngDummy.Formula
rngDummy.Formula = strOldFormula
End Function
Please also note the change in the If statement of CopyReds (now it calls the above function).
I think that your algorithm should be redesigned: instead of testing the cells displayed color, check if the value is below a limit. This limit can be calculated with WorksheetFunction.Small, which returns the n-th smallest element.
Sub CopyReds()
Dim sPrice As Worksheet: Set sPrice = Sheets("Prices")
Dim sResult As Worksheet: Set sResult = Sheets("Result")
Const colPriceName As Long = 2 ' The column in which cells can be colored red and contains the names to copy
Const clrCopy As Long = 13551615 ' The color which indicates that the cell should be copied (red)
Const colResult As Long = 2 ' The column where the results should be copied
Const rowResultFirst As Long = 2 ' First row on sResult to use for output
Const lngCount As Long = 10 ' Copy lngCount lowest elements (the actual number may be higher due to ties)
Const colSort As Long = 2 ' The column in which cells contain the values from which the lowest lngCount should be selected
Dim varLimit As Variant: varLimit = Application.WorksheetFunction.Small(sPrice.UsedRange.Cells(2, colSort).Resize(sPrice.UsedRange.Rows.Count - 1, 1), 10)
Dim rowResult As Long: rowResult = rowResultFirst
Dim rowPrice As Long: For rowPrice = 2 To sPrice.UsedRange.Rows.Count - sPrice.UsedRange.Row + 1 ' Loop until last row
If sPrice.Cells(rowPrice, colSort).Value <= varLimit Then
sResult.Cells(rowResult, colResult).Value = sPrice.Cells(rowPrice, colPriceName).Value
rowResult = rowResult + 1
End If
Next rowPrice
End Sub
Based on the screenshots, I revised the code:
Sub CopyReds()
Dim sPrice As Worksheet: Set sPrice = Sheets("Prices")
Dim sResult As Worksheet: Set sResult = Sheets("Result")
Const rowResultFirst As Long = 2 ' First row on sResult to use for output
Const rowPriceFirst As Long = 2 ' First row on sPrice to process
Const lngCount As Long = 10 ' Copy lngCount lowest elements (the actual number may be higher due to ties)
Const colDate As Long = 1 ' The column which contains the dates
Const colValueStart As Long = 2 ' The column where values start
Dim rowResult As Long: rowResult = rowResultFirst
Dim rowPrice As Long: For rowPrice = rowPriceFirst To sPrice.UsedRange.Rows.Count - sPrice.UsedRange.Row + 1 ' Loop until last row
Dim colResult As Long: colResult = 1
sResult.Cells(rowResult, colResult).Value = sPrice.Cells(rowPrice, colDate).Value
colResult = colResult + 1
Dim varLimit As Variant: varLimit = Application.WorksheetFunction.Small(sPrice.Cells(rowPrice, colValueStart).Resize(1, sPrice.UsedRange.Columns.Count - colValueStart + 1), lngCount)
Dim colPrice As Long: For colPrice = colValueStart To sPrice.UsedRange.Columns.Count - colValueStart + 1
If sPrice.Cells(rowPrice, colPrice).Value <= varLimit Then
sResult.Cells(rowResult, colResult).Value = sPrice.Cells(rowResultFirst - 1, colPrice).Value
colResult = colResult + 1
End If
Next colPrice
rowResult = rowResult + 1
Next rowPrice
End Sub
Just to clarify my comment, you need to "advance" either the Cells(j, i) or the Offset(j, 0).
If you decided to use For loops, try to stick with it for both cases:, see code below:
For j = 2 To 217
For i = 2 To 1086
Debug.Print sPrice.Cells(j, i).Interior.Color ' <-- for Debug only
If sPrice.Cells(j, i).Interior.Color = 13551615 Then
sPrice.Cells(j, i).Copy Destination:=sResult.Cells(2, 2).Offset(j, 1)
End If
Next i
Next j
I am using Excel 2010.
I have some working VBA code that compares two cells (from text, to text) and generates the redlined text into a third cell with strikethroughs on removed words, underlines on added words. This is not a straight combination of the contents of the cells.
The code works, but I think it can be more efficient with the use of multidimensional arrays to store things instead of using additional cells and recombining. But I am stuck on how to implement it. I would also like to determine where the breaking point is, especially for newer versions of Excel that I don't have yet, since the number of characters allowed in a cell seems to continually grow with every new release.
Comments are also welcome.
The working code:
Sub main()
Cells(3, 3).Clear
Call Redline(3)
End Sub
Sub Redline(ByVal r As Long)
Dim t As String
Dim t1() As String
Dim t2() As String
Dim i As Integer
Dim j As Integer
Dim f As Boolean
Dim c As Integer
Dim wf As Integer
Dim ss As Integer
Application.ScreenUpdating = False
t1 = Split(Range("A" + CStr(r)).Value, " ", -1, vbTextCompare)
t2 = Split(Range("B" + CStr(r)).Value, " ", -1, vbTextCompare)
t = ""
f = False
c = 4
ss = 0
If (Range("A" + CStr(r)).Value <> "") Then
If (Range("B" + CStr(r)).Value <> "") Then
j = 1
For i = LBound(t1) To UBound(t1)
f = False
For j = ss To UBound(t2)
If (t1(i) = t2(j)) Then
f = True
wf = j
Exit For
End If
Next j
If (Not f) Then
Cells(r, c).Value = t1(i)
Cells(r, c).Font.Strikethrough = True ' strikethrough this cell
c = c + 1
Else
If (wf = i) Then
Cells(r, c).Value = t1(i) ' aka t2(wf)
c = c + 1
ss = i + 1
ElseIf (wf > i) Then
For j = ss To wf - 1
Cells(r, c).Value = t2(j)
Cells(r, c).Font.Underline = xlUnderlineStyleSingle ' underline this cell
c = c + 1
Next j
Cells(r, c).Value = t1(i)
c = c + 1
ss = wf + 1
End If
End If
Next i
If (UBound(t2) > UBound(t1)) Then
For i = ss To UBound(t2)
Cells(r, c).Value = t2(i)
Cells(r, c).Font.Underline = xlUnderlineStyleSingle ' underline this cell
c = c + 1
Next i
End If
Else
t = Range("A" + CStr(r)).Value
End If
Else
t = Range("B" + CStr(r)).Value
End If
lc = Range("XFD" + CStr(r)).End(xlToLeft).Column
Call Merge_Cells(r, 4, lc)
Application.ScreenUpdating = True
End Sub
Sub Merge_Cells(ByVal r As Long, ByVal fc As Integer, ByVal lc As Long)
Dim i As Integer, c As Integer, j As Integer
Dim rngFrom As Range
Dim rngTo As Range
Dim lenFrom As Integer
Dim lenTo As Integer
Set rngTo = Cells(r, 3)
' copy the text over
For c = fc To lc
lenTo = rngTo.Characters.Count
Set rngFrom = Cells(r, c)
lenFrom = rngFrom.Characters.Count
If (c = lc) Then
rngTo.Value = rngTo.Text & rngFrom.Text
Else
rngTo.Value = rngTo.Text & rngFrom.Text & " "
End If
Next c
' now copy the formatting
j = 0
For c = fc To lc
Set rngFrom = Cells(r, c)
lenFrom = rngFrom.Characters.Count + 1 ' add one for the space after each word
For i = 1 To lenFrom - 1
With rngTo.Characters(j + i, 1).Font
.Name = rngFrom.Characters(i, 1).Font.Name
.Underline = rngFrom.Characters(i, 1).Font.Underline
.Strikethrough = rngFrom.Characters(i, 1).Font.Strikethrough
.Bold = rngFrom.Characters(i, 1).Font.Bold
.Size = rngFrom.Characters(i, 1).Font.Size
.ColorIndex = rngFrom.Characters(i, 1).Font.ColorIndex
End With
Next i
j = j + lenFrom
Next c
' wipe out the temporary columns
For c = fc To lc
Cells(r, c).Clear
Next c
End Sub
You can directly assign Excel Range object to VBA 2d-array and perform all that business logic operations on that array. It will provide substantial performance boost vs range iteration. The result values then can be inserted back into Excel worksheet column from that 2d-array.
Sample code snippet follows:
Sub Range2Array()
Dim arr As Variant
arr = Range("A:B").Value
'alternatively
'arr = Range("A:B")
'test
Debug.Print (arr(1, 1))
End Sub
Another useful technique is to assign Excel's UsedRange to VBA Array:
arr = ActiveSheet.UsedRange
Hope this may help. Best regards,
Sample code not quite right
I've got a spreadsheet with the following "original" and "changed" content:
Tesla to Begin Trial for Allowing Other Vehicles from Other Electric Vehicle Automakers to Use Tesla Superchargers
Tesla to Begin Trial for Allowing Other Vehicles from Other EV Auto Makers to Use Tesla Superchargers
Running your code, I got not-quite-right results.
The "original" text that is missing from the "changed" version is correctly shown with strikethrough, but the new text in the "changed" version is just ... missing.
Alternative approach
Poking around, it looks like you're trying to re-create MS Word's Track Changes formatting.
Why not just leverage Word?
The following VBA code does just that. This requires that your Excel VBA project has a reference to the Word object library. You can add this from within the VBA editor by clicking Tools → References, and selecting Microsoft Word XX.Y Object Library, where XX.Y is whatever version you have installed.
Public Sub CompareCells()
' ####################
' Basic Flow
'
' 1. Get the text content of the two cells to compare.
' 2. Get an open instance of MS Word, or spin up a new one.
' 3. Use Word's text-comparison features to generate the tracked-changes markup.
' 4. Copy that markup to the clipboard.
' 5. Then just paste that into our target cell.
' ####################
Const Src As String = "A" ' Column containing the original source text
Const Tgt As String = "B" ' Column containing the targeted text to compare
Const Cmp As String = "C" ' Column where we will put the marked-up comparison
Const RowToUse As Integer = 8 ' Rejigger as appropriate to your use case.
' 1.
Dim ThisSheet As Excel.Worksheet: Set ThisSheet = Excel.ActiveSheet
Dim StrSrc As String, StrTgt As String
StrSrc = ThisSheet.Range(Src & RowToUse).Value
StrTgt = ThisSheet.Range(Tgt & RowToUse).Value
' 2.
Dim Wd As Word.Application: Set Wd = GetApp("Word")
' 3.
Dim DocOrig As Word.Document, DocChgd As Word.Document, DocMarkup As Word.Document
Set DocOrig = Wd.Documents.Add(Visible:=False)
DocOrig.Content = StrSrc
Set DocChgd = Wd.Documents.Add(Visible:=False)
DocChgd.Content = StrTgt
Set DocMarkup = Wd.CompareDocuments(DocOrig, DocChgd, wdCompareDestinationNew)
' 4.
DocMarkup.Content.Copy
' 5.
ThisSheet.Range(Cmp & RowToUse).Select
ThisSheet.Paste
' Cleanup
DocOrig.Close savechanges:=False
DocChgd.Close savechanges:=False
DocMarkup.Close savechanges:=False
End Sub
Public Function GetApp(AppName As String) As Object
Dim app As Object
On Error GoTo Handler
Set app = GetObject(, AppName & ".Application")
Set GetApp = app
Exit Function
On Error GoTo 0
Handler:
If Err.Number > 0 And Err.Number <> 429 Then ' Unknown error, so error out
Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext
Exit Function
End If
DoEvents
' If we get here, there's no open app by that name, so start a new instance.
Set app = CreateObject(AppName & ".Application")
Set GetApp = app
End Function
When run using the same sample texts, I get the following:
This time, we get both the removed text in strikethrough, and the added text in underlining, with color coding as well.
So I'm pretty new to vba, and have only been learning it for about a month for work. I keep having this problem where I get the Error 1004 "Application defined, or object defined error" when I try to run my macro. What I'm trying to do is to go through a list of data, and find out if a row has a specific code attached to it. If it does I want to move a date on that row to a new sheet.
Sub k0Pop()
Dim source As Long
Dim servR As Integer
Dim servC As Integer
Dim patID As Integer
Dim spot1 As Integer
Dim spot2 As Integer
Dim sht1 As Worksheet
Dim sht2 As Worksheet
Set sht1 = Sheets("Sheet2")
Set sht2 = Sheets("Sheet4")
servR = 3
For source = 3 To 100000
servC = 2
While sht2.Cells(source, 2) < sht2.Cells(patID, 15)
source = source + 1
Wend
While Cells(source, 2) = Cells((source + 1), 2)
If Cells(source, 6) = "K045A" Then
spot = source
End If
source = source + 1
Wend
If Cells(source, 6) = "K045A" Then
spot = source
source = source + 1
End If
spot2 = source
source = spot1
While (Cells(spot, 5) - Cells(source, 5)) < 365
source = source - 1
Wend
While source < spot
sht1.Cells(servR, servC) = sht2.Cells(source, 5)
source = source + 1
servC = servC + 1
Wend
sht1.Cells(servR, 14) = sht2.Cells(spot, 5)
source = spot2
servR = servR + 1
patID = patID + 1
Next
End Sub
Looks like patID is 0, which is an invalid column. Use F8 to single cycle. Hover over a variable to see its value. Use debug.print's to show intermediate data.
I have already looked at a few examples of how to use Application.OnTime,
to check for progress within the cell before updating and wrote up an implementation but I'm not sure why it wont work.
I dont want to paste the whole thing here, because it may be more confusing than just looking at the subs within the workbook.
I was wondering if someone with experience with this type of thing would be willing to look at my code. I can pm the file I'm working on.
Here is the method that loads data into the shell sheet. Ideally the data will all load before the pattern_recogADR sub is run... otherwise there is an error.
Sub build_singleEquity()
'x As Long
Dim x As Long
x = 6
'Dim x As Long
'x = 4
Application.ScreenUpdating = False
Call DefineTixCollection 'creates table of inputs
'check
'Debug.Print TixCollection(4).ORD
'set up data points - from "Input" sheet
'Dim x As Long
'Dim path As String
'path = Sheets("Input").Range("V1").value
'For x = 1 To TixCollection.Count
Sheets("SingleEquityHistoryHedge").Activate
'clear inputs
Range("B2:B8").Clear
Dim Inputs() As Variant
Dim name As String
name = "SingleEquityHistoryHedge"
'insert new inputs
Inputs = Array(TixCollection(x).ADR, TixCollection(x).ORD, TixCollection(x).ratio, _
TixCollection(x).crrncy, TixCollection(x).hedge_index, TixCollection(x).hedge_ord, _
TixCollection(x).hedge_ratio)
Call PrintArray(2, 2, Inputs, name, "yes") ' prints inputs
Dim last_row As Long
last_row = Range("A" & Rows.count).End(xlUp).Row
Range("AN11") = "USD" & TixCollection(x).crrncy
Range("AA11") = "USD" & TixCollection(x).crrncy
' Dim sht_name As String
'Application.Run "RefreshAllStaticData"
BloombergUI.ThisWorkbook.RefreshAll
' sht_name = TixCollection(x).ADR
' Call Sheet_SaveAs(path, sht_name, "SingleEquityHistoryHedge") 'save collection of sheets
'Next x
'Call TriggerCalc
'check this out
Call pattern_recogADR(x + 4, 5, 13)
End Sub
Here is the pattern_recogADR sub.... as you can see I have tried a ton of different thing which are commented out.
Sub pattern_recogADR(pos As Long, pat_days As Long, sht_start As Long)
'
'Application.Wait Now + "00:00:20"
'Dim pat As pattern
'Dim tix As clsTix
Dim newTime As Date
newTime = Now + TimeValue("00:00:30")
Do While Not Now >= newTime
'add back in as parameters
'Dim pos As Long
Dim x As Long
'Dim pat_days As Long
'Dim sht_start As Long
'************************
'pos = 5
'pat_days = 5
'sht_start = 13
Sheets("SingleEquityHistoryHedge").Activate
'Sleep 20000 'sleeps
Dim st As Long
Dim st_num As Long
Dim st_end As Long
Dim count As Long
Dim patrn As Long
count = sht_start
Dim i As Long
Dim j As Long
Dim patPLUSret() As Variant
Dim k As Long
Dim z As Long
k = 2
z = 3
For j = 8 To 12
'**************************************
count = sht_start
st_num = sht_start
st_end = 13
If IsNumeric(Cells(count, j).value) Then
'sets default pattern to beginning cell value
' Debug.Print st_num
If Cells(st_num, j).value < 0 Then
For i = count + 1 To count + 1 + pat_days
If IsNumeric(Cells(i, j).value) Then
If Cells(i, j).value < 0 Then
st_end = i
'Debug.Print st_end
End If
Else
Exit For
End If
Next i
patrn = st_end - st_num
' Debug.Print count
' Debug.Print patrn
ReDim Preserve patPLUSret(k * 2 + 1)
patPLUSret(0) = Range("B2").value 'ADR
patPLUSret(1) = Range("B3").value 'ORD
patPLUSret(k) = patrn
patPLUSret(z) = Application.WorksheetFunction.Average(Range(Cells(st_num, j), Cells(st_end, j)))
' Debug.Print patPLUSret(j)
' Debug.Print patPLUSret(j + 1)
st_num = sht_start 'resets starting point to initial
st_end = sht_start
' For x = 4 To 6
' If Range("L" & x).value = "x" Then
' ReDim Preserve mac_array(x - 4)
' mac_array(x - 4) = Range("N" & x).value
' End If
' Next x
' check this out
'tix.arbPnl = patrn
'save to separate class for patterns
'TixCollection.Add tix, tix.ADR
'******************************
ElseIf Cells(st_num, j).value > 0 Then
For i = count + 1 To count + 1 + pat_days
If IsNumeric(Cells(i, j).value) Then
If Cells(i, j).value > 0 Then
st_end = i
End If
Else
st_end = st_num
Exit For
End If
Next i
patrn = st_end - st_num
ReDim Preserve patPLUSret(k * 2 + 1)
patPLUSret(0) = Range("B2").value 'ADR
patPLUSret(1) = Range("B3").value 'ORD
patPLUSret(k) = patrn
patPLUSret(z) = Application.WorksheetFunction.Average(Range(Cells(st_num, j), Cells(st_end, j)))
' Debug.Print patPLUSret(j)
' Debug.Print patPLUSret(j + 1)
st_num = sht_start 'resets starting point to initial
st_end = sht_start
' Debug.Print patrn
'pat.arbPnl = patrn
'save to separate class for patterns
End If
k = k + 2
z = z + 2
Else
count = count + 1
st_num = count
End If
'
' k = k + 1
'new_array = patPLUSret
Next j
' Debug.Print patPLUSret
Sheets("PatternADR_ORD").Activate
Range(Cells(pos, 1), Cells(pos, 10)) = patPLUSret
Loop
End Sub
If you wait or loop to simulate a wait in your second sub, it won't give the control back to the spreadsheet and your formulae won't update.
Instead of
Call pattern_recogADR(x + 4, 5, 13)
why don't you call:
Application.onTime "'pattern_recogADR ""x + 4"", ""5"", ""13""'"
I am trying to copy paste a row of values from one sheet to another but keep coming up with the run-time error 1004: Application-defined or object-defined error.
the error is in the first line of the two below and I do not know where I am going wrong.
Set copyRange = Worksheets("Sheet2").range(A & i + 1 & CA & i + 1)
copyRange.Copy Destination:=Cells(countD, 2)
the code needs to copy a line at a time and paste it into the default sheet.
Edit
full code
Dim List1 As range
Dim List2 As range
Dim lastRow As Integer
Dim countD As Integer
Dim found As Boolean
Dim copyRange As range
Set List1 = ThisWorkbook.Sheets("Sheet1").range("H2:H600")
Set List2 = ThisWorkbook.Sheets("Sheet2").range("I2:I600")
countD = 2
lastRow = Application.CountA(ThisWorkbook.Sheets("Sheet2").range("C:C"))
For i = lastRow To 2 Step -1
found = False
value1 = List1.Item(i, 1)
For Each value2 In List2
If value1 = value2 Then
found = True
Exit For
End If
Next
If found = False Then
Set copyRange = Sheets("Sheet1").range("A" & i + 1 & "CA" & i + 1)
copyRange.Copy Destination:=Cells(countD, 2)
Sheets("Discrepancies").Cells(countD, 1) = "name not found"
ThisWorkbook.Sheets("Sheet1").Cells(i + 1, 1).EntireRow.Delete
Cells(countD, 8).Interior.ColorIndex = 3
countD = countD + 1
End If
Next
Exactly as Vasim's comment mentions - with the addition of a colon : in front of the CA
Sub copyRangeOver()
Dim i As Integer
i = 6
Dim copyRange As Range
Set copyRange = ThisWorkbook.Worksheets("Sheet2").Range("A" & i + 1 & ":CA" & i + 1)
Dim countD As Integer
countD = 10
copyRange.Copy Destination:=Cells(countD, 2)
End Sub