how can i check if an instance of a workbook already exist? During my programm i would be able to close excel without the application crash...
When i'm using the instance in the programm i want to check if the instance exist when not, i open it again...
thanks
Dim neue_excelinstanz As excelapp.Application
Dim neue_workbook As excelapp.Workbook
Dim neue_worksheet As excelapp.Worksheet
neue_excelinstanz = CType(CreateObject("Excel.Application"), Microsoft.Office.Interop.Excel.Application)
neue_workbook = CType(neue_excelinstanz.Workbooks.Open("C:\Users\global.xlsx"), Microsoft.Office.Interop.Excel.Workbook)
neue_worksheet2 = CType(neue_workbook.Worksheets(2), Microsoft.Office.Interop.Excel.Worksheet)
Would it maybe just be an If block? Im not sure how to code in German, but:
If neue_workbook Is Nothing Then
neue_workbook = CType(neue_excelinstanz.Workbooks.Open("C:\Users\Nicolas Grichting\Desktop\Vmc_vapeur\global.xlsx"), Microsoft.Office.Interop.Excel.Workbook)
End If
I would maybe also use threading.sleep to give it time to load before having the program try it again. But this depends on how youre using this.
Related
I wanted to open an existing ppt using Wscript and modify it. For that I am opening the file in visual studio editor and executing the script from cmd in windows using WScript hi.vbs
But when I ran the same code I am getting error.
Expected end of statement in line 4
Line 4 looks like Dim objNewPowerPoint As Object
However Same case works when I run code in excel VBA editor.
When I am removing the As object I am not getting any error nor any changes are happening in the PPT file.
Wondering what is the possible issue.
I am not using excel vba or word vba i am just running the file from cmd
Sub Open_an_existing_Presentations()
Dim objNewPowerPoint As Object
Dim MyPresentation As Object
Dim pSlides As Object
Set objNewPowerPoint = CreateObject(PowerPoint.Application)
'Make this Application Object Visible
objNewPowerPoint.Visible = True
Please help me how can i modify and more importantly how to see both errors compile and syntax.
FYI : I am completely new into VBA and I am trying to update a PPT and wanted to run vba script from another program so trying something like this. Best suggestions are always welcome
In VBScript you cannot dim something as something.
Dim objNewPowerPoint
Dim MyPresentation
Dim pSlides
And dim is optional and serves no technical purpose in VBS (it merely catches spelling mistakes if Option Explicit is specified, else it does nothing at all as in your case except take time to the process the line). In compiled languages it allocates storage and checks data types when using it.
When you use Set = VBS knows it an object and makes it one (4 x 32 bit integers - One a reference count and another a memory address of the function table for the object - two are unused). If you use x=5555 vbs knows it's a integer.
VBA code works great:
Sub testVBA()
Dim wb As Object ' Lotus123.Document
Set wb = GetObject("S:\Temp\T\0375D.WK3", "Lotus123.Workbook")
End Sub
VB.net code fails:
Sub TestVBNet()
Dim wb As Object ' Lotus123.Document
wb = GetObject("S:\Temp\T\0375D.WK3", "Lotus123.Workbook")
End Sub
In VB.net I get a FileNotFoundException: "File name or class name not found during Automation operation."
As I can run it from VBA that means the file exists and that the class name exists. So why doesn't it work and how can I fix it in VB.net.
EDIT: I guess I'm not sure how to start diagnosing this: Obviously the class exists on my computer but somehow VB.net doesn't manage to find it. Maybe VB.net uses a different method to activate the class. Maybe a registry entry is missing. I am glad for any suggestions.
Edit 2: I also tried using CreateObject and got this error: "Cannot create ActiveX component." Not unexpected.
For some reason VB.net cannot find the class name "Lotus123.Workbook" so I tried getting the file without the class name and it works fine in XP.
Dim wb As Object ' Lotus123.Document
wb = GetObject("S:\Temp\T\0375D.WK3")
EDIT: In Win8 64bit the above doesn't work; just hangs.
The code below works in XP 32 bit as well as in Win8 64 bit. I checked with process monitor what is happening under the hood. CreateObject checks for the CLSID in the registry using the given object. Then it looks up the necessary info using the CLSID.
Public Shared Function GetLotusWB(ByVal sFile As String) As Object
'HKCU takes precedence if exists
'HKCU\Software\Classes\Lotus123.Workbook\CLSID
'HKCU\Software\Classes\CLSID\{29130007-2EED-1069-BF5D-00DD011186B7}
'normally this is used because Lotus123 doesn't create HKCU entries
'HKCR\Lotus123.Workbook\CLSID = {29130007-2EED-1069-BF5D-00DD011186B7}
'HKCR\CLSID\{29130007-2EED-1069-BF5D-00DD011186B7}\InprocHandler32 = ole32.dll
'HKCR\CLSID\{29130007-2EED-1069-BF5D-00DD011186B7}\LocalServer32 = C:\Lotus\123\123w.exe
'using object as that sometimes works better
Dim LotusObj As Object = CreateObject("Lotus123.Workbook")
'get application
'need a reference to Lotus 123 else declare as Object
Dim LotusApp As Lotus123.Application = LotusObj.Application
'FAILS: LotusApp.Visible = True
'open file; also works fine As Lotus123.Document
Dim ldoc As Object = LotusApp.OpenDocument(sFile)
'visible and activate (must declare as Object else gives exception)
Dim appObject As Object = ldoc.Application
appObject.Visible = True
ldoc.Activate()
Return ldoc
End Function
This works great because it creates the "Lotus123.Workbook" which is used to get the application object.
Load the file into an Excel workbook. It should be able to convert the lotus123 workbook on the fly.
First of all, check to make sure your inclusions (I think under Tools menu, includes or references or something like that) include the library that references Lotus123.Document. Chances are it's in the "Microsoft Excel 14.0 Object Library" or similar.
I've heard it said that VB is not VBA!
I'm a total noob trying to create a blank MS Access database using VBA in Excel. I want to name the new database "tblImport". This is the code I´m using:
Sub makedb()
Dim accessApp As Access.Application
Set accessApp = New Access.Application
accessApp.DBEngine.CreateDatabase "C:\tblImport.accdb", dbLangGenera
accessApp.Quit
Set accessApp = Nothing
End Sub
I get the following error message:
"Run Time Error 3001: Application Defined or Object Defined Error"
What can I do?
The name of the locale constant in the CreateDatabase method is wrong:
This:
accessApp.DBEngine.CreateDatabase "C:\tblImport.accdb", dbLangGenera
Should be:
accessApp.DBEngine.CreateDatabase "D:\tblImport.accdb", DB_LANG_GENERAL
Change that and your code should work. (It does for me at least).
Old Question. Here are my two cents. You have a typo...
dbLangGenera should be dbLangGeneral
More about it in Workspace.CreateDatabase Method (DAO)
Voting to close this question as per Dealing with questions with obvious replies
Try this. This works.
Sub makedb()
Dim accessApp As Access.Application
Set accessApp = New Access.Application
accessApp.DBEngine.CreateDatabase "C:\tblImport.accdb", dbLangGeneral
accessApp.Quit
Set accessApp = Nothing
End Sub
EDIT: Will delete this answer and post it as a comment once the post is closed.
Old question, but it was useful for me. Seems like you don't even need Access object.
Access.DBEngine.CreateDatabase "D:\tblImport.accdb", DB_LANG_GENERAL
works fine for me.
You should use the first method if you intend to use the automation object you've created. You can open forms, use DoCmd statements, etc., simply by prefacing each statement with "accessApp." For example, I use TempVars to hold user data. I can open a related database using automation, then do
accessApp.TempVars.Add "CurrentUser", TempVars.CurrentUser
to pass the CurrentUser value from the active database to the new database.
When all you want to do is create a new database to do a function such as DoCmd.TransferDatabase on, you can just use
Access.DBEngine.CreateDatabase "D:\tblImport.accdb", DB_LANG_GENERAL
I am trying to open another db using VBA from my current db then close the one I am in. When I use the code listed here it opens Access but closes it immediately. I am sure it is simply something I am overlooking but the past hour I have wracked my brain. Any help would be greatly appreciated.
Private Sub Command115_Click()
Dim objAccess As Access.Application
Const conPATH = "C:\Users\user\Desktop\Database1.accdb"
'Create an instance of the Access application object.
Set objAccess = CreateObject("Access.Application")
'Open the database
objAccess.Visible = True
objAccess.OpenCurrentDatabase conPATH
'Open the form.
objAccess.DoCmd.OpenForm "Main-Form"
' Maximize other Access window
objAccess.DoCmd.RunCommand acCmdAppMaximize
End Sub
Thanks in advance for any help in this matter
If you use the shell then when you close your first database, the second will remain open.
Sub test()
Dim sh As Variant
sh = Shell("""C:\...\MSACCESS.EXE"" ""C:\...\FileName.accdb""")
End Sub
My guess the reason your code didn't work is because, the second access you start is an object that exists within the first one. The moment the first one closes and cleanup starts for its objects/variables. It closes the second one.
Say your first app is access1 and it is trying to open access2 and then close access1 app and makes access2 as active app. One thing you could do is,
Once your access1 app loads try to open access2 app programatically and make it visible and then use Application.closeCurrentdatabase to close access1 database and then in the unload event of access1 apps form (if there is any form in access1 app) call Application.Quit.
This works.
I'm deploying an early bound styled VBA module that needs Scripting.Dictionary and RegExp.
The script, predictably, fails when it runs on another computer.
The user has to go to Tools->Reference in the VBA IDE and add a reference to those two libraries manually to make it work.
Hence lies the problem. Asking the non-technical end user to go to the IDE and manually add references is asking way too much of them.
The other alternative is to rewrite the whole (very long script written by someone else) to use late binding. I rather not take this path if there are other methods.
As an altervative, some people suggest adding a reference programatically like so:
Application.VBE.ActiveVBProject.References.AddFromFile [Path to library]
Is this the correct solution and if so are there any downsides of this strategy?
If not, are there other methods that will to enable the code to remain early bound yet does not require references to be added manually by the user.
Suggestions involving direct calls to the Win32/64 API are also welcome.
Thanks.
In my own limited environment (small # of other people using spreadsheets I develop, relatively standard machine setups), if I create the file and add the references, and then give a copy to someone else, they can open it with no problems and not have to do anything, so keep that in mind with this answer. (I'm wondering why that doesn't work for you.) Also, this was with Excel.
Rather than adding a reference from a file path, you might consider using the GUID property instead.
Here is some code I once used to automatically create references in a newly created workbook. (It's part of a script that would export code, references, and unit tests on worksheets to text for use with Subversion and then later reconstitute the workbook from the text files.) You might find it useful to your situation. (EH and cleanup removed to keep it short...)
'Export refs in existing workbook to text file
Private Sub exportRefs_(srcWbk As Workbook)
Dim fs As FileSystemObject
Set fs = New FileSystemObject
Dim tsout As TextStream
Set tsout = fs.CreateTextFile(fs.BuildPath(getTargetPath_(srcWbk), "refs.refs"))
Dim ref As Reference
For Each ref In Application.ThisWorkbook.VBProject.References
Call tsout.WriteLine(ref.GUID)
Next ref
'<EH + cleanup...>
End Sub
'Add refs to newly created workbook based on previously exported text file
Private Sub importRefs_(wbk As Workbook, path As String)
Dim fs As FileSystemObject
Set fs = New FileSystemObject
Dim tsin As TextStream
Set tsin = fs.OpenTextFile(path)
Dim line As String
Dim ref As Reference
While Not tsin.AtEndOfStream
line = tsin.ReadLine()
Set ref = Nothing
On Error Resume Next
Set ref = wbk.VBProject.References.AddFromGuid(line, 0, 0)
On Error GoTo 0
If ref Is Nothing Then
Debug.Print "add failed: " & line
End If
Wend
'<EH + cleanup...>
End Sub
Like, I said, limited environment, but hopefully it helps.