VBA Code in Excel randomly stops executing. No error messages occur - excel

Essentially, I have an Updata button that takes information from two columns, in two spreadsheets (within 1 book). The overall goal of this code is to take all the values from one column, and then append the values from the other column below it.
Worksheets("Overall Flow").Range("A4:A1004").Value = Worksheets("Active").Range("A2:A1002").Value
Dim i As Integer
For i = 4 To 1004
If Worksheets("Overall Flow").Range("A" & Trim(str(i))) = "" Then
Worksheets("Overall Flow").Range("A" & Trim(str(i)) & ":A" & Trim(str(1000 + i))).Value = Worksheets("Inactive").Range("A2:A1002").Value
i = 1005
End If
Next
For some reason, the first line executes, and then finishes. When I put break points, then do step-by-step, no other steps happen afterwards.
When I run the first line individually, it appears to work fine, but not when:
Worksheets("Overall Flow").Range("A" & Trim(str(i)) & ":A" & Trim(str(1000 + i))).Value = Worksheets("Inactive").Range("A2:A1002").Value
or
Worksheets("Overall Flow").Range("A4:A1004").Value = Worksheets("Inactive").Range("A2:A1002").Value
is present aftwards.

Solution to this is very unusual.
CTRL+BREAK CTRL+BREAK CTRL+BREAK ESC
It just happened to me againg after long time, I was looking for a solution and I came here then this sequence came back to my mind and I tried.
It worked for me, I hope this will help someone.

Update: Tweaked code (now with error checking!)
Main points concerning the current code:
When copying the ACTIVE range, check for last consecutive cell used. This is faster and more effecient than a loop.
Why are you trimming a number you know will not contain spaces?
There's no need to set i = 1005, just use Exit For. This is more effecient and clear to the reader what the intention is. I don't use this in the code below since I avoided looping altogether.
Here's a different way you can do this without any looping, which I think is more clear and effecient. Try this and see if it works for you:
Sub test()
Dim lastRow As Long, offSet As Long
lastRow = Worksheets("Active").Range("A2").End(xlDown).row
'Sanity checks
If IsEmpty(Worksheets("Active").Range("A2")) = True Then offSet = 1: lastRow = 2
If lastRow > 1001 Then lastRow = 1002
Worksheets("Overall Flow").Range("A4:A" & lastRow + 2).Value = _
Worksheets("Active").Range("A2:A" & lastRow).Value
If lastRow < 1002 Then
Worksheets("Overall Flow").Range("A" & lastRow + (3 - offSet) & _
":A1004").Value = Worksheets("Inactive").Range("A2:A1002").Value
End If
End Sub
Notes:
Sanity check 1 is for if A2 is blank in the Active sheet.
Sanity check 2 is for if there are cells beyond A1002 with values in Active sheet.

This is what I am using to test your code. Since I don't know what's in the spreadsheets, I can't reproduce exactly what you're seeing so I'm first putting dummy data into the ranges.
For me it is running fine every time, and I've tried it on 2 different computers - Excel 2003, and Excel 2010.
I set a breakpoint and stepped with F8, and also Shift F8 and both worked fine.
Something may be different with your data (i.e. the first cell being copied over from the inactive sheet is blank and therefore execution stops after processing the first cell -- check that column A4 is not blank), or perhaps some memory has gotten corrupted from having Office being killed.
In a Module I have:
Sub test()
Worksheets("Active").Range("A2:A1002").Value = "active"
Worksheets("Active").Range("A5").Value = ""
Worksheets("Inactive").Range("A2:A1002").Value = "inactive"
Worksheets("Overall Flow").Range("A4:A1004").Value = Worksheets("Active").Range("A2:A1002").Value
Dim i As Integer
For i = 4 To 1004
If Worksheets("Overall Flow").Range("A" & Trim(Str(i))) = "" Then
Worksheets("Overall Flow").Range("A" & Trim(Str(i)) & ":A" & Trim(Str(1000 + i))).Value = Worksheets("Inactive").Range("A2:A1002").Value
i = 1005
End If
Next
End Sub
Have you tried the same code on another computer?

I had this issue and I tracked it down to custom VBA functions used in Conditional Formatting that was processed while application.screenupdating was still set to True.
I'm not sure how consistent this behaviour is but, when a custom VBA function is referred to in a conditional formatting rule, when the screen updates, it will not step through the code even when employing break points or the debug.assert method. Here's the breakdown of what happened:
Context:
2 open workbooks.
Conditional formatting and custom function in question were in workbook1.
The code I was attempting to execute was in workbook2.
Process
I call a procedure in workbook2.
Workbook2's procedure reaches a line executing an autofilter command.
Autofilter command triggers a screen update in all open workbooks (any command that triggers a Worksheet_Change or Worksheet_Calculate event can apply here).
Screen update processes the conditional formatting rules, including the rule in workbook1 calling workbook1's custom function.
Custom function is run in a 'silent' state (i.e. with no interaction with user, ignoring break points and "debug.assert" calls; this appears to be by design as part of the conditional formatting feature)
Custom function finishes execution and ceases all other active code execution.
I fixed my problem by adding a Application.ScreenUpdating = False line at the start to prevent screen updates and, by extension, conditional format processing (but it's best to keep custom functions away from conditional formatting to begin with).
I'm not sure if this is relevant to your situation at all but I hope it helps somebody.

It has already been mentioned in transistor1's answer, but only as a side comment.
I had a similar problem, that VBA code simply stopped executing in the middle of a function. Just before that it also jumped back a few lines of code. No Error Message was shown.
I closed all open Excel programs, and upon reopening the File everything worked fine again.
So my confirmed Answer to this problem is: Corrupted Memory, restart Excel.
Edit: after doing this, I also encountered the Problem that Visual Basic Editor crashed when I tried uncommenting a particular line. So I created a New Excel file and copied my code. Now I don't have any problems anymore.

I ran into the same problem. I had a sub routine that gave random errors throughout the code without giving error messages. By pressing F8, the code would resume.
I found someone had posted a Subroutine he called "ThatCleverDevil" I do not remember the resource or who posted it. It would warn you an error was about to occur. The routine is posted below.
I split the code into component sub-routines. The short snippits ran with no interruption or erros. I created a subroutine that called each snippit. Errors resumed.
They would run individually, but not all together.
RESOLUTION: Between called sub-routines, I ran the following line of code:
Application.Wait Second(Now) + 1
The code then ran without error.
Thanks to whomever it was that wrote ThatCleverDevil. And special thanks to the coder who wrote about Application.Wait.
Sub ThatCleverDevil()
On Error GoTo err
MsgBox "About to error"
err.Raise 12345
MsgBox "Got here after the error"
Exit Sub
err:
Stop: Resume
End Sub
Robert

VBA simply is prone to this issue. I have used it for years in corproate workflows because it is so hardcoded into lots of things, but if possible I would just consider alternatives. If this an ad-hoc project R will be faster and offer more flexibility. If this is more production oriented and meant to handle large volumes I would consider informatica.

To improve the performance I called the function DoEvents inside the loop. It solved the problem for me.

Related

Selecting cell in Excel VBA used to work but now generates Run-time error '1004': Method 'Range' of object '_Global' failed

The simplified sub below shows line XX1 started to fail yesterday with the above error message. I have tried it on another machine and it fails at the same point.
This code has run hundreds of times, albeit with frequent minor updates. I use this kind of method for selecting a range quite frequently and it usually works fine. It's code that I've written for my own use at work, but aiming to eventually share it with colleagues (for execution and possible ownership). It's part of a 2000-line VBA process.
I've included an earlier fragment of code with a similar line 'xx0' that works fine.
I've found that line XX1 works if I put in an arbitrary selection task beforehand like this: Range("A1").Select
Also, as a test I entered line XX2 and that works fine if I skip over line XX1.
Worse, after experiencing the error, the code continues to run (apparently normally) and then at a later point, it crashes catastrophically: Excel shuts down completely with no warning or message.
I can see that lines xx0 and xx1 are both giving Excel a task to create an address by appending a 'Long' variable to a string like "j2:j" and I guess this is not good practice (it kind of undermines the use of Option Explicit and my Dim statements), but I'm not sure how best to fix it (considering my code contains many subs / 2000 lines and is full of this kind of structure).
Option Explicit
Sub AlignTables()
Dim LastRow As Long
Dim RefColX As Integer
Sheets("shMAIN").Select
LastRow = Cells(999999, 1).End(xlUp).Row
RefColX = Rows("10:10").Find(What:="x1", LookAt:=xlWhole, MatchCase:=False).Column
'Sort shMAIN
Range("c11:c" & LastRow).CurrentRegion.Select
Selection.Sort Header:=xlYes, Key1:=Cells(10, RefColX), Order1:=xlDescending, Key2:=Range("c10"), Order2:=xlAscending
'Refresh index column
Range("c11:c" & LastRow).Select 'Line XX0
Selection.FormulaR1C1 = "=ROW()"
Selection = Selection.Value
'Prepare sort key in ShCleanData column J
Sheets("ShCleanData").Select
LastRow = Cells(999999, 1).End(xlUp).Row 'This sets LastRow to value 6981
Range("j2:j" & LastRow).Select 'Line XX1
Range("j2:j" & "6981").Select 'Line XX2
'(subsequent lines populate the column etc)
End Sub
One option could be to change all my referencing to style YY:
Range(Cells(2,10), Cells(LastRow, 10)).Select 'Style YY
Range("j2:j" & LastRow).Select 'Style XX (easier to follow)
... but I find style XX easier to follow (and easier to explain to people with no VBA knowledge who may need to run and support my code).
KEY QUESTIONS:
Would declaring LastRow as Variant (instead of Long) be a robust
solution to this? [Not only to maintain the 'readable' style, but
also to simplify modifying all my subs]
Or should I go through my code removing Range Selections of type XX and changing them all to style 'YY'?
Or is there some other better solution?
One other strange observation that may be relevant: I have a VBA Function: jStop ("Run this section stepwise if you're processing data of type XX") I use this function throughout my code with different messages. The jStop function simply displays the string in a msgbox together with 'Click OK to continue or Cancel to Stop' and handles the user's request to stop (or not). It has been working for many months, but yesterday just before I encountered the 'XX1' issue, I noticed that this function was ignoring the text argument (it behaved like jstop ("") ) ... perhaps this gives a clue about what's behind the XX1 issue? This odd behaviour of jStop did not persist after a reboot.

What are the reasons UnMerge will not work in Access VBA?

I have a VBA macro in Access 2016 (actually, written for earlier version, but right now I'm working with 2016). What it does is adjusting several Excel spreadsheets, and moving them to another location, while also writing some logs into SQL table.
One of adjustments is unmerging some merged cells. The weird part is, those excel files fail to process at times (not always), when this Access DB is triggered programmatically (from another macro in another Access DB). When I launch it manually, or go into debug step-by-step, it always works - so I am confused, and can't find the reason.
I tried to replace "MergeCells = False" for "Unmerge" - it's the same. I also tried to make new ACCDE file - no result.
This is part of the code, where the unmerging occurs.
xlsh.Select
xlsh.Range("A1:D1").Select
xlsh.Outline.ShowLevels RowLevels:=2
With Selection
.UnMerge
End With
xlsh.Range("A1").Value = "Alfa"
xlsh.Range("B1").Value = "Bravo"
xlsh.Range("C1").Value = "Golf"
xlsh.Range("D1").Value = "Tango"
xlsh.Range("A1").Select
If xlsh.Range("A1").Value = "" Then GoTo error
When it fails to unmerge the cell, the value won't get assigned, and at the end it's empty, thus, continues to label 'error'.
Try this one:
xlsh.("A1:D1").Unmerge
Instead of
xlsh.Select
xlsh.Range("A1:D1").Select
xlsh.Outline.ShowLevels RowLevels:=2
With Selection
.UnMerge
End With
The last 2 lines are unnecesary as:
If xlsh.Range("A1").Value = "" Then GoTo error
Will not be true as you are assigning a value a few lines before. (xlsh.Range("A1").Value = "Alfa")

Excel VBA Function stops execution before completion without error message

I set out to write a simple function to determine the length of a string in points. Having googled around I decided to avoid the font metrics problem by having excel do the work for me.
Here is the code.
Option Explicit
Function txtWidthPts(MyText As String) As Integer
'A cell on a working worksheet has been named "WidthTest" for easy reference & to ensure data is not overwritten.
'set WidthTest word wrapping off so that strings placed in there aren't wrapped
Application.ScreenUpdating = False
With [WidthTest]
.WrapText = False
.Value = MyText
'autofit WidthTest
.Columns.AutoFit
'get the width of the column
txtWidthPts = .Width
.ClearContents
End With
End Function
I tested the function by placing it in a cell on a working worksheet thus:
=txtWidthPts("Test123")
When I have this working I will be using it in code not as a worksheet function.
My problem is that the function does not throw an error and stops execution on the line:
.Value = MyText
I have placed the code and name into an empty workbook to ensure no interaction with other workbook contents / code.
I have searched extensively and tried various suggestions (DoEvents, Application.Update = False, etc, etc.) to no result.
I have cleared all breakpoints, closed and opened the workbook & restarted. I have tested with options set to Break on All Errors.
No result.
I suspect I am missing something obvious but it has me beat at the moment.
Any and all suggestions will be most welcome.
So, #YowE3K was right on the money. After fixing the error in the original code (Corrected code above) this runs fine from vba. I knew I was missing something obvious.
Curiosity sub-question: the function works as desired and indeed, as #YowE3K observed, it does not modify the Excel environment. However the result returned is dependent on it appearing to have modified the Excel environment. Seriously WTF. Just wanting to understand.
Thanks again YoWE3K.

VBScript - Either getting object required or type mismatch errors

I have scoured the web and this site looking for an answer on this, so I would really appreciate some help.
I'm creating a VBScript to do some modifications to a user-specified Excel spreadsheet. I have the first part of my script working fine, but the second part is driving me nuts. I need it to search the first column for a value and, if found, delete the row. Right now I'm not worrying about the deletion statement--I'm doing testing by seeing if I can get the For Each statement to run properly as well as the If Then statement. Here's the specific block of code:
For Each cell in objSheet.Columns("A:A").Cells
Set cell = objSheet.Columns("A:A").Cells
If cell.Value = "60802400040000" then
cell.font.bold = True
End If
Next
I have tried many variations of this and cannot find the right combination. Initially I was getting an "Object Required" messages, and after reading a number of posts, found that I needed to put in a Set statement for cell, which I did. Now I am getting a Mismatch Type error message.
The funny thing is, before I put in the Set statement, the code would execute, but it would throw the Object Required error when I closed the spreadsheet. After adding it, the error for the Type Mismatch pops up immediately.
Most examples I keep finding on the web are for VBA, and I try to modify them for VBS, which I don't know very well. Any assistance anyone can give me will be greatly appreciated.
You are redefining cell, cell is defined automatically in the For Each statement.
Delete this line
Set cell = objSheet.Columns("A:A").Cells
This is an example from Help, unfortunately Help doesn't have any examples that uses For Each, only For x = n to n and other means. For Each is the right thing to do.
Set r = Range("myRange")
For n = 1 To r.Rows.Count
If r.Cells(n, 1) = r.Cells(n + 1, 1) Then
MsgBox "Duplicate data in " & r.Cells(n + 1, 1).Address
End If
Next n
For vba to vbs, you have to create the object and use, as some objects are automatically available in VBA (like app object) - Set exceldoc = CreateObject("c:\blah\blah.xls) then to use Set r = exceldoc.worksheets(0).range("MyRange").
Also you have to use constant values not names as vbscript can't look them up.

Excel error 1004 "Unable to get .... property of WorksheetFunction class" appearing inconsistently

I have a VBA function within a spreadsheet which operates on another spreadsheet that is opened in an earlier stage of my macro. The macro used to work fine but just recently has started causing a 1004 error ("Unable to get RoundDown property of the WorksheetFunction class") when it runs.
I believe I understand what the error would be caused by (a problem running RoundDown) but I cannot see why it is getting triggered in my macro and the odd part is that when I go into Debug mode and step through the code in the VBE the error does not recur (despite nothing obviously changing).
Does anyone have a similar experience of this sort of error occuring inconsistently and know what I could do to resolve it?
I'm reasonably VBA/Excel-savvy, but any suggestions on further steps to diagnose it would be appreciated. I am wondering if there is some issue with the opened spreadsheet not being ready but I cannot see how.
The code is here. The error occurs on the line marked with a comment.
Public Function GetDatesA(sWorkbookname As String, sSheetname As String, sCell As String) As Variant
Dim vDateList() As Variant
Dim currentCell As Range
Dim n As Long
Set currentCell = Workbooks(sWorkbookname).Worksheets(sSheetname).Range(sCell)
n = 0
Do
If Trim(currentCell.Value) = "" Then
Exit Do
Else
ReDim Preserve vDateList(0 To 1, 0 To n)
vDateList(0, n) = WorksheetFunction.RoundDown(currentCell.Value, 0) 'error occcurs on this line
vDateList(1, n) = currentCell.Column
'Debug.Print currentCell.Value
End If
Set currentCell = currentCell.Offset(0, 1)
n = n + 1
Loop While currentCell.Column < XL_LAST_COLUMN
GetDatesA = vDateList
End Function
Other details are:
Excel version: 2010
File being opened resides locally on my C: drive; my macro is in a spreadsheet on the network
File format for both files is .xls (i.e. Excel 2003) - I don't have the option of changing this
Windows 7 (not that I think it would be relevant)
Two points I've tried already are:
Substitute a different worksheet function (e.g. Min(currentCell)) and that also causes the same problem
Having the file open already seems to stop the problem - I wonder if there is some way that the workbook which is being opened (rather than my main workbook with the macro in it) is not enabled for macros and this is interfering. But even if this is the cause I'm not sure how to get around it!
Any ideas?
This error occurs often when any argument passed to the worksheet function is not of the correct type or simply doesn't make sense.
For example, I've had this problem when calling WorksheetFunction.Asin with an argument bigger than 1. In your case, I'd guess currentCell.Value is a non-numeric value or one not according to your region settings regarding numbers.
Yes, the error message is really misguiding.
I got the "Unable to get * property of WorksheetFunction Class" error using Transpose, MMult,MDterm, and MInverse functions.
I was able to get my code to run by putting "Option Base 1" in the Declarations (before the actual code) section of the particular Module in the Editer.
Excel assumes "Option Base 0" which will add an extra row and column of empty cells. This will cause the error to occur and isn't immediately obvious to see.
I have come accross this before, and for me it was becase the criteria range made no sense, as Andre said above.
See example formula below:
.Cells(11, i).Formula = Application.WorksheetFunction.CountIfs(Sheets("Sheet1").Range("AC8:C" & n), "S")
Have a look at the Range... it makes no sense. Amended the range from "AC8:C" to "AC8:AC" and it will work perfectly

Resources