Application.Interactive = True fails - vba

In the worksheet SelectionChange event I set :
Application.Interactive = False
.... do work
Application.Interactive = True
For some reason Interactive is not getting set back to true, even though I know the code is being executed.
Excel 2013
Any ideas?

Sub Main()
Debug.Print Application.Interactive
Application.Interactive = False
Debug.Print Application.Interactive
Application.Interactive = True
Debug.Print Application.Interactive
End Sub
Doesn't fail for me... Try that and see more here
Since you've discovered the reason for failing the conclusion could be that the Application.Volatile needs to be set to false on a function that uses it because the Interactive mode blocks the user interface and the Volatile calculates things based on user input. While the user input is blocked you can't expect a function that evaluates the user input to work. One excludes the other - hope that makes sense.
Additionally, check your on error resume next or on error goto <label> statements as the would cause skipping some of the code therefore the Application.Interactive = True would have never get executed.

Related

Where name created with "Application.Names.Add" go?

For learning and work purposes I needed to create mesage box that pop-ups first only first time opening workbook. For that task I found elegant solution in one of the old treads (old thread).
Working principle of sugested code is more or less clear to me exept part where named created with Application.Names.Add go? I checked under Forlulas -> name manager and did not find created name, I gues it went somwhere else?
Used Code:
Sub RunOnce()
Dim Flag As Boolean: Flag = False
For Each Item In Application.Names
If Item.Name = "FunctionHasRun" Then Flag = True
Next
If Flag = False Then
Call Application.Names.Add("FunctionHasRun", True, False)
Application.DisplayAlerts = False
ActiveWorkbook.Save
Application.DisplayAlerts = True
Call RunOnceFunction
End If
End Sub
Formulas -> Names only shows you the ThisWorkbook.Names and Worksheet.Names (depending on the scope of your Name).
If you insert a breakpoint and look at View > Locals Window you can find the Application.Names in Me > Application > Names.
My preferred method of adding an "opened" flag is to add to the CustomDocumentProperties. I've never seen anyone use Application.Names for this.
If what you want is for a messagebox to pop up when the workbook is opened then the following code will do that for you, simply place it under ThisWorkbook.
Also I'm pretty sure the syntax in your code is incorrect, if you wanted to add a Named Range you would do it as follows: Sheet1.Range("A1:Z10").Name = "MyNamedRange" there would be no need for the Call before it, as it isn't calling another subroutine/function:
Private Sub Workbook_Open()
MsgBox "This will pop up when the Workbook is opened!", vbInformation, "My MessageBox Title"
End Sub
UPDATE:
If you only want it to run the very first time the workbook is opened and then never again, the following will achieve that for you:
Sub RunOnce()
Dim Flag As Boolean: Flag = False
For Each Item In Application.Names
If Item.Name = "FunctionHasRun" Then Flag = True
Next
If Flag = False Then
Sheet1.Range("$A$1:$A$1").Name = "FunctionHasRun"
Application.DisplayAlerts = False
ActiveWorkbook.Save
Application.DisplayAlerts = True
Call RunOnceFunction
End If
End Sub
You cannot see it in the Name Manager because your third argument, Visible:=False, is set False.
Visible - True specifies that the name is defined as visible. False specifies that the name is defined as hidden. A hidden name does not appear in the Define Name, Paste Name, or Goto dialog box. The default value is True .
See Names.Add Method for more information.

VBA getting error Active method of Worksheet class failed

I tried to look for answers but am not finding anything that has worked so far. I have some code that works for some people and doesn't work for others (using same version of Excel) when running this code:
Private Sub Workbook_Open()
Application.ScreenUpdating = False
Application.ExecuteExcel4Macro "SHOW.TOOLBAR(""Ribbon"",False)"
Application.DisplayFormulaBar = False
Sheets("Discount").Activate
ActiveSheet.Unprotect Password:="01"
ActiveSheet.Range("G14:O15,O18:O19,D29:I29,D31:I31,D33:I33,D35:I35,D37:I37").ClearContents
ActiveSheet.Shapes("Option Button 31").ControlFormat.Value = xlOn
OptionButton31_Click
Application.ScreenUpdating = True
End Sub
The error shows up at Sheets.("Discount").Activate
the spelling of the worksheet is correct. I also tried
Private Sub Workbook_Open()
ActiveWorkbook.Unprotect Password:="01"
Application.ScreenUpdating = False
Application.ExecuteExcel4Macro "SHOW.TOOLBAR(""Ribbon"",False)"
Application.DisplayFormulaBar = False
ThisWorkbook.Sheets("Discount").Activate
ActiveSheet.Unprotect Password:="01"
ActiveSheet.Range("G14:O15,O18:O19,D29:I29,D31:I31,D33:I33,D35:I35,D37:I37").ClearContents
ActiveSheet.Shapes("Option Button 31").ControlFormat.Value = xlOn
OptionButton31_Click
ActiveWorkbook.Protect Password:="01"
Application.ScreenUpdating = True
And still getting the error. I am having a hard time figuring it out because it works for me every time, but doesn't for other people.
Solution 1:
Instead of Sheets.("Discount").Activate write Sheets("Discount").Activate and it should work. E.g., remove the dot.
Solution 2:
If this does not work, try to make sure that this sheet is visible. E.g. write before the line with the error the following:
Sheets("Discount").Visible = True
In general, in VBA try to avoid ActiveSheet, ActiveWorkbook, ActiveCell -
How to avoid using Select in Excel VBA
As noted by #Mat's Mug, consider using Worksheets("Discount").Visible, when you refer to Worksheets, because the Sheets collection contains Charts as well.
Try using:
Sheets("Discount").Visible
Sheets("Discount").Select
If this doesn't work, let me know and I'll see if there's anything else I can recommend. If you make a note of any error messages, this may help. Also, try running it with screenupdating not turned off as the person above suggested - then you will see if there's a specific action that's making it fall over.

assign value of a cell when a user is inside of a cell

I tried creating a while loop to make sure it was set in case the user was typing but it seems like the macro magically stops when it tries to assign a value and the user is already typing something.
Basically how do you stop a macro from ending from this unexpected situation and how can I detect if the user is blocking?
from your comments you have a misconception of how VBA works.
first, a macro run from a module is taking control of the workbook, you can't detect user input in a while or for loop like that, what you want is to use an event listener like in this tutorial: a good site for vba basics
basiclly use the "Private Sub Worksheet_Change" option for a sheet/workbook.
also, if you're monitoring just one cell, check out this how to use worksheet change
Function IsEditing() As Boolean
If Application.Interactive = False Then
IsEditing = False
Exit Function
End If
On Error GoTo err:
Application.Interactive = False
Application.Interactive = True
IsEditing = False
Exit Function
err:
IsEditing = True
Exit Function
End Function

Workbook.CheckIn always produces an error the first time it's called?

I have some workbooks stored in a document library on Sharepoint 2007. I want to check out a workbook, modify it, and check it back in.
Using the following code:
Option Explicit
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Sub test()
Dim bk As Workbook
Dim path As String
path = "http://sharepoint/sites/test/TEST_Relink.xlsm"
If Workbooks.CanCheckOut(path) Then
Application.DisplayAlerts = False
Workbooks.CheckOut path
DoEvents
Set bk = Workbooks.Open(path, False)
bk.Sheets("test").Range("h1").Value = "modified " & Now
DoEvents
Sleep 10000
bk.checkIn True
Application.DisplayAlerts = True
End If
End Sub
The bk.checkIn call always produces the following run-time error:
Method 'CheckIn' of object '_Workbook' failed
After I go into Debug, I press F5 to continue and the check-in always occurs successfully.
I added the 10-second delay with Sleep 10000 because I was thinking that maybe the check-out was taking a while to propagate to the server. But no matter how much time I set for Sleep, this same issue keeps occurring. Any thoughts?
EDIT:
I tried using a looped check of .CanCheckIn as follows:
While Not bk.CanCheckIn
DoEvents
Wend
bk.checkIn True
This gave the same error.
For those finding this like I did, I had
Workbooks(logFileName).CheckIn SaveChanges:=True, Comments:="New row added from " & mainFile
This produced the error message like yours, however on entering debug and pressing f5 would action. So here is my complex solution.....I just split out the code to the following
Workbooks(logFileName).Save
Workbooks(logFileName).CheckIn Comments:="New row added from " & mainFile
Hope this helps others.
Use this:
Dim xl As Excel.Application
Set xl = CreateObject("Excel.Application")
xl.AutomationSecurity = msoAutomationSecurityForceDisable
xl.EnableEvents = False
xl.DisplayAlerts = False
'code to checkin/checkout
xl.EnableEvents = True
xl.DisplayAlerts = True
You probably already figured it out but I thought I'd post it for anyone else who comes here looking for an answer.
If you are setting SaveChanges to True then you MUST also set Comments to be a String (a null value won't do)
So in your example you would need to do this:
bk.CheckIn True, ""

VBA - range.sort script unexpectedly runs other script it shouldn't run

I'm working on a workbook and I'm getting an error which is driving me crazy. I really have no idea what's going wrong here.
On the main worksheet (Bestandsübersicht) I have a combobox named ddBestand. On the change event of that combobox it runs a script that checks if certain buttons should be enabled or disabled. The code for this is:
Private Sub ddBestand_Change()
On Error GoTo ExitSub
Dim i As Integer
i = 3
Dim WS As Worksheet
Set WS = Sheets("Bestandsübersicht")
If ddBestand.Value = "" Then GoTo ExitSub
Do Until WS.Cells(i, 1).Value = ddBestand.Value
i = i + 1
Loop
If WS.Cells(i, 13).Value = 0 Or _
Right(Sheets("Bestandsübersicht").Range("AL1").Value, 3) <> "yes" Then
btnNetwork.Enabled = False
Else
btnNetwork.Enabled = True
End If
btnChange.Enabled = True
btnSpecifics.Enabled = True
btnCopy.Enabled = True
Exit Sub
ExitSub:
btnChange.Enabled = False
btnSpecifics.Enabled = False
btnNetwork.Enabled = False
btnCopy.Enabled = False
End Sub
This works totally fine when I use ddBestand. But sometimes when I run other scripts this script unexpectedly starts to run, even though those scripts do not relate to eachother. For example, when I run the initialize even for a userform (which is launched from another worksheet) it starts to run at this range.sort method:
Sheets("DB_Network").Columns("A:C").Sort key1:=Sheets("DB_Network").Range("A2"), _
order1:=xlAscending, Header:=xlNo
it gives the error 1004 (Unable to set the Enabled propert of the OLEObject class (which is logica, because as we're on another worksheet, the property for those buttons is wrong). As I didn't know how to stop the first script from running, I fixed the script by changing the OLEObjects to this:
Sheets("Bestandsübersicht").OLEObjects("btnChange").Object.Enabled = True
Solving the symptoms might not be the prettiest solution, but as I couldn't find out what the problem really was, I decided this was a suitable solution. But it got crazier. I'm still using another version of this document as I need it for my work. Somehow the same sort method started running the same script in the other document, which made the same error occur. Now I really want to solve this problem, as I don't want it to unexpectedly run scripts in other documents. Is there anybody out here who can help? Would be much appreciated!
I would guess that your combobox is directly linked to a range using the ListFillRange and/or LinkedCell properties. That is not a good idea for precisely this reason. I suggest you use code to populate the control using its .List property instead, which is easier and faster than .AddItem:
Sheets("Bestandsübersicht").OLEObjects("ddBestand").Object.List = Sheets("blah").Range("A2:A100").Value
for example.