Set objBAPIControl = CreateObject("SAP.Functions") - vba

At line Set objBAPIControl = CreateObject("SAP.Functions") I face the runtime error 429
ActiveX component can't create object.
The script was initially running in a 32 bit system now it is upgraded to 64 bit.
This is the logon script:
Private Sub SAP_Initialize_Objects()
Set objBAPIControl = CreateObject("SAP.Functions")
Set sapConnection = objBAPIControl.Connection
bln_SAP_Objects_Initiated = True
End Sub
If sapConnection.IsConnected <> 1 Then

If you use MS Office 64 bits (I say "if" because in a 64 bits OS, MS Office 32 bits can be used), and SAP GUI 32 bits, then it won't work by default.
There are 3 possible solutions/workarounds:
Install SAP GUI for Windows 7.70 which is the first version to be 64 bits
Use the feature "DLL Surrogate" by changing the registry -> See this stack overflow answer
Convert VBA into VBScript that you run in 32 bits (outside your MS Office application)
Dim <var> As <type> in VBA ▶ Dim <var> in VBScript
etc. (search Web for differences, e.g. this (non-exhaustive) Microsoft document)

Related

Why are some Windows registry values readable by VBScript but not VBA?

I'm trying to read a registry value using VBScript and VBA.
This works in VBScript but in VBA it returns the read error below:
Set objshell = CreateObject("WScript.Shell")
ID = objshell.RegRead("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProductID")
And I noted that I can't actually see the value in the regedit app with/without running as administrator. Is this something to do with registry virtualisation?
UPDATED BASED ON REGISTRY REDIRECTION COMMENTS
Since the code above runs on 64 bit Office, it should be possible to craft something like this, but the 32 bit part still throws an error.
#If Win64 Then ' 64 bit Office
Debug.Print CreateObject("WScript.Shell").RegRead("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProductID")
#Else ' 32 bit Office
Debug.Print CreateObject("WScript.Shell").RegRead("HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\ProductID")
#End If

Telling VBA to look at 64-bit registry view

I want to assign an ArrayList to a variable.
Sub Create_ArrayList()
Dim arrL As Object
'Creating an ArrayList, option 1 - fails
Set arrL = CreateObject("System.Collections.ArrayList")
'Creating an ArrayList, option 2 - fails
Set arrL = GetObject("New:{6896B49D-7AFB-34DC-934E-5ADD38EEEE39}")
End Sub
Both options fail :
Run-time error '-2146232576 (80131700)':
Automation error
I found that the CLSID exists in the registry in HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID
The Office is 32-bit and Windows is 64-bit. I am not familiar with the registry, but it seems from what I have read, that 32-bit Office is trying to find ArrayList in some 32-bit Windows location (view), while it actually is in 64-bit location. Can it be the case? How to make the application get ArrayList from the correct location?
It seems, to access an alternative registry view, I should somehow use the flag KEY_WOW64_64KEY (value 0x0100), but the examples that I found are too big to comprehend (eg1, eg2). I don't want to edit registry data, I only want to tell VBA that I am using 64-bit Windows, so the object that I need is to be found somewhere else than it expects.

Conditional mechanism in Word VBA

I have a .dot file with one line of code that must be executed in a Microsoft Word macro if and only if the version of Word 2003 or greater is installed, otherwise it shuold be ignored. I tried to implement it like this, hoping that Visual Basic for Word compiles a line only if it needs to execute it. The code in question is the following (Word 2003 is 11.0)
If Val(Application.Version) >= 11 Then
ActiveWindow.View.ReadingLayout = False
End If
I still want that the .dot file with the macro is usable in earlier versions of Microsoft Word, such as Microsoft Word 2000.
However, if I try to run the .dot file, it fails on Word 2000 with a compile error because ActiveWindow.View.ReadingLayout is not a valid method in Word 2000. That is, even when the line will never be executed on Word 2000 because Application.Value will be 9.0, Word still tries to compile that line.
Is there any way in Visual Basic for Word to add compiler directives so that some code is not compiled depending on the Word version?
We ended up implementing it with late binding, which turned out to be a very small tweak:
If Val(Application.Version) >= 11 Then
Dim obj As Object
Set obj = GetObject(, "Word.Application")
obj.ActiveWindow.View.ReadingLayout = False
End If
Their are two tricks to get it working:
1)
Add a module for functions that work only in specific office version and add your subroutines to it.
2)
In places where you have to call your functions, add a test for the specific Office Version and then call your subroutine with Application.Run
The original Module would have:
If Val(Application.Version) >= 11 Then
Application.Run "office11module.disableReadingLayout"
End If
And your specific Module office11module would have
Public Sub disableReadingLayout()
ActiveWindow.View.ReadingLayout = False
End Sub
This works because Word is not compiling the office11module until it is needed, and we make sure through the Application.Run call that Word does not know that we need it before runtime.
Our Word VBA Products require a Digital Signature.
We utilize MS Office 2000 as a base development application in order to be as backward compatible as possible with some of our clients.
We utilized the solution provided by jonas_jonas (Jan 16 '14 at 17:59) for years while using Word 2000 on Windows XP development platforms.
However - after upgrading to Windows 7 Pro development platforms, the solution no longer worked, giving us "Disk full" errors when attempting to save the Word files after having digitally signed them.
We then tried, and successfully used, the answer (above) provided by Pep (Jan 18 '14 at 23:23) which works when you need to Digitally Sign the Word file.
We figured the "disk full" error was a result of the attempt to compile the project before saving.
If Val(Application.Version) >= 11 Then
Dim obj As Object
Set obj = GetObject(, "Word.Application")
obj.ActiveWindow.View.ReadingLayout = False
End If

Cannot instanciate a NotesUIWorkspace from VBA (Word)

The source situation: I have an Notes Application which uses MS Office 2000 under Windows XP. The new situation has to be MS Office 2010 under Windows 7. IBM Notes is 8.5.3FP3.
The old one uses a VBA template to communicate with Notes which works properly. At one time a Notes.NotesUiWorkSpace object is created to open a document, navigate to a richtext item, select all the content (formatted) and copy to the clipboard. Then the clipboard content ist pasted into the Word document via VBA. That works fine.
The same code in the second environment doesn't work anymore. I noticed that the Notes.NotesUIWorkSpace object cannot be instanciated in VBA. No errors, no hints. Only the runtime error when I reference the workspace-object later.
Here is a code excerpt:
' this is a profile document which is filled correctly
Call prof.Save(True, True)
Call prof.replaceItemValue("Form", "Profile")
' setting up the ui
dim WS as Object
set WS = CreateObject("Notes.NotesUiWorkSpace")
Set uiprof = WS.EditDocument(True, prof)
' Set uiprof = WS.currentDocument
If uiprof.editMode Then Call uiprof.gotofield("RT")
Call uiprof.SelectAll
Call uiprof.Copy
Call uiprof.Close
' later on the clipboard will be pasted into the word document
Any ideas what could be the cause here? I am setting up an environment with XP, MS Office 2010 and Notes tonight to check it out that it is not caused by Windows 7.
If the Windows 7 machine is 64 bit, take a look at the answers here. Note that those refer to the COM classes (lotus.), and you are using the OLE classes (notes.), but I believe the 64/32 bit issue applies to both.

VB6 Copy Array AutoCAD

I'm in the process of transfering our VBA AutoCAD script to VB.NET but i came across a warning. VB.net 2010 give me a warning that this code is obsolute, and probally won't work with 64 bit.
The program needs to be 64 compatibel because of the problems with our vba file and AutoCAD 2012 & Windows 7 X64. What do i need to use instead of VB6.CopyArray?
If Flipline = True Then
P1 = VB6.CopyArray(Endpoint)
P2 = VB6.CopyArray(Beginpoint)
Else
P1 = VB6.CopyArray(Beginpoint)
P2 = VB6.CopyArray(Endpoint)
End If
According to MSDN documentation for Support.CopyArray:
The Visual Basic 6.0 Variant data type is no longer supported in Visual Basic 2010. The CopyArray function is used by the upgrade tools to copy an Array to or from a Variant array.
To copy an array in Visual Basic 2010, use the Clone, Copy or CopyTo methods of the Array class.
Array.Clone Documentation
If Endpoint is an array, then:
P1 = Endpoint.Clone()