I noticed that Office 2010 comes with Visual Basic for Applications 7.0. However I can't seem to find much documentation on what changes were made. Does anyone have a summary of the changes, or any resources describing the differences?
There's not a whole lot that has changed between VBA6 and VBA7. VBA7 was introduced to support 64-bit versions of both Office and Windows (see below on what those differences are). Here are the key changes:
64-bit support, primarily for API
calls. This is both used to make your code work with your OS/Office version as well as others' (i.e. someone on Office 2003/WinXP)
If you are on a 64-bit version of
Windows, but are on a 32-bit version
of Office, you can declare API calls
like below.
.
#If Win64 Then
Declare PtrSafe Function GetTickCount64 Lib "kernel32"() As LongLong
#Else
Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
#End If
If you are on a 64-bit version of
Windows, and are on a 64-bit version
of Office, you can declare API calls
like:
.
#If VBA7 Then
Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" ( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As LongPtr
#Else
Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal _
lpClassName As String, ByVal lpWindowName As String) As Long
#End If
To support this, there are:
Three new keywords (2 data types and
1 modifier): LongPtr, LongLong and PtrSafe
One new function: CLngLng() (i.e.
Int64)
The new compilation constants as used
above: VBA7 and Win64
This piece on MSDN has more on the changes in VBA 7 for Office 2010:
http://msdn.microsoft.com/en-us/library/ee691831(loband).aspx#odc_office2010_Compatibility32bit64bit_IntroducingVBA7CodeBase
VBA7 is compatible with 64-bit versions of Office.
There are other changes as well... I'm having users in the field report that code which functioned properly in 2007 no longer works and shows errors.
Example, this works in VBA6 (Excel 2007)
PRINT STRING$(80,"=")
mynewdata = MID$(mydata, 15,4)
It prints out a line made of "=" characters as a visual break, then looks at mydata, jumps over 15 characters and gets 4 of them, the result is stored in mynewdata. It fails in VBA7 (Excel 2010).
I did find a potential workaround...
PRINT VBA.STRING$(80,"=")
mynewdata = VBA.MID$(mydata, 15,4)
OR
PRINT VBA.STRING(80,"=")
mynewdata = VBA.MID(mydata, 15,4)
A complete list of changes would still be helpful... and/or a file converter.
Related
I'm currently updating a document for our company that no longer runs when used on a 64bit Microsoft Office suite (32bit remains fine).
I understand that functions and declarations require the 'Ptrsafe' word to be added - but when I add it to this function it tells me the syntax is wrong
Private PtrSafe Function executeSingle(Optional rurl As String = vbNullString, _
Optional qry As String = vbNullString, _
Optional complain As Boolean = True, _
Optional sFix As String = vbNullString _
) As cJobject
I have no idea why though...it works fine if you remove PtrSafe. Any ideas?
You should only need to use the "Declare" statement when you declare a reference to an external procedure in a dynamic-link library (DLL). It is always recommended that you use the PtrSafe keyword when doing this. Like A.S.H. said, you don't need to do this for your own functions. See this link for more info.
Here is an example from MSDN of the correct syntax for using PtrSafe. It includes conditional compilation syntax, which might be useful in your situation:
Declare PtrSafe Function GetActiveWindow Lib "User32" () As LongPtr
#If Vba7 Then
' Code is running in 32-bit or 64-bit VBA7.
#If Win64 Then
' Code is running in 64-bit VBA7.
#Else
' Code is not running in 64-bit VBA7.
#End If
#Else
' Code is NOT running in 32-bit or 64-bit VBA7.
#End If
I'm using this Windows API call in 32-bit Excel, and it's working fine:
Declare Function WNetGetConnection Lib "MPR.DLL" _
Alias "WNetGetConnectionA" ( _
ByVal lpszLocalName As String, _
ByVal lpszRemoteName As String, _
lSize As Long) As Long
I'm told that a small percentage of our corporate users will soon be going to 64-bit Excel. I don't have access to 64-bit Excel and I haven't been able to find any coworkers nearby who do.
According to this file, if I'm reading it correctly...
http://www.cadsharp.com/docs/Win32API_PtrSafe.txt
...this is the correct syntax of that function for 64-bit Excel:
Declare PtrSafe Function WNetGetConnection Lib "MPR.DLL" _
Alias "WNetGetConnectionA" ( _
ByVal lpszLocalName As String, _
ByVal lpszRemoteName As String, _
lSize As Long) As Long
But is that correct? The only difference is adding PtrSafe. Should it point to a different, 64-bit version of MPR.DLL? Also, should lSize be LongLong rather than Long?
But is that correct?
Yes. But don't take my word for it. Get a copy of Office and test it.
The only difference is adding PtrSafe. Should it point to a different, 64-bit version of MPR.DLL?
No. Windows chooses the appropriate DLL for the bitness of your process. For standard WinAPI components, you should only use the DLL name, and never a full path. Windows will pick the correct one.
Also, should lSize be LongLong rather than Long?
It should be ByRef Long. The WNetGetConnection documentation shows the function prototype:
DWORD WNetGetConnection(
_In_ LPCTSTR lpLocalName,
_Out_ LPTSTR lpRemoteName,
_Inout_ LPDWORD lpnLength
);
DWORD is a 32 bit unsigned integer.1 LPDWORD is a pointer to a DWORD, which in VB(6/A) is ByRef lpnLength As Long.
As a bonus:
In the Windows API LONG is also 32 bit. This does not change whether you're running 32 or 64 bit. (sizeof(DWORD) == sizeof(LONG) == sizeof(INT))
VBA Data Types
1Fun Fact: VBA doesn't have unsigned integer types, since VB6 didn't have them. VB6 came out in '98.
A brand-new never-before-used single user license for Office 2016 is running about $150 as of 7-Oct-15. It's also available through the MSDN subscription programs. It's also available at many fine retailers. (I'm intentionally not posting links.)
I found this answer:
Declare Function SetComputerName Lib "kernel32" Alias "SetComputerNameA" ( _
ByVal lpComputerName As String _
) As Long
but it dont work for me,
could you please show me how to change computer name in vb.net
You may not simply paste Declared definitions from VB6 to VB.NET.
In .NET you don't use Alias "SetComputerNameA" to call ANSI version of the function. The runtime manages this, and VB now supports both Ansi and Unicode.
VB6's Long matches to VB.NET's Integer.
Declare Auto Function SetComputerName Lib "kernel32" (ByVal lpComputerName As String) As Integer
The answer to my question may already be out there, but I am having no success synthesizing the data into a coherent solution. Your advice is appreciated.
I am writing a "User Control" application using Visual Basic (.NET 3.5) and Visual Studio 2012. I have been given a DLL file which contains functionality that I must access. Additionally, I have been given corresponding .LIB and .H files, which I am told will be necessary to properly make use of the DLL. I believe the DLL was written in C.
I have also been provided with some older VB code which is said to make use of the DLL's functions one that DLL is "included" (or something) in the project. As you can probably tell, my grasp on this is tenuous at best. Here is the VB code:
Private Declare Function SF_AddToCommandQueue Lib "SFrmUt80.dll" Alias "_SF_AddToCommandQueue#8" _
(ByVal CmdCode As Integer, ByVal strParam As String) As Boolean
Private Declare Function SF_FlushCommandQueue Lib "SFrmUt80.dll" Alias "_SF_FlushCommandQueue#4" _
(ByVal strWindowTitle As String) As Boolean
Private Declare Function SF_GetUserName Lib "SFrmUt80.dll" Alias "_SF_GetUserName#8" _
(ByVal strBuffer As String, ByVal BufferSize As Integer) As Integer
Private Declare Function SF_GetUserID Lib "SFrmUt80.dll" Alias "_SF_GetUserID#0" _
() As Integer
Private Declare Function SF_GetCmdType Lib "SFrmUt80.dll" Alias "_SF_GetCmdType#0" _
() As Integer
Private Declare Function SF_GetCmdFilename Lib "SFrmUt80.dll" Alias "_SF_GetCmdFilename#8" _
(ByVal strBuffer As String, ByVal BufferSize As Integer) As Integer
Private Declare Function SF_GetRegisteredMsg Lib "SFrmUt80.dll" Alias "_SF_GetRegisteredMsg#0" _
() As Integer
Hoping this is not too vague, I am wondering how I go about integrating this DLL file into my solution, so that I may make use of its functionality in VB .NET.
Your wisdom is very much appreciated. Thank you!
The .H-files won't be of much use to you, as you don't use them in the managed environment. You would actually just include the DLLs into your solution (i.e. add them to the project in the Solution-Explorer).
VS does the rest for you, all you need to do is, as you already did, declare the functions from the library in your source-code and call the functions.
On MSDN there is an article on this.
I have some VB 6.3 code that's normaly used on a 32 bit machine.
But I am now trying to run it on a 64bit machine and the code doesn't work.
It was programmed in VBA (autodesk)
Can someone help me with converting?
Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, _
ByVal dwProcessID As Long) As Long
Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long
See Compatibility Between the 32-bit and 64-bit Versions of Office 2010 for a list of affected API calls and examples of conditional compilation to call either the 32- or 64-bit Declare statement depending on the bitness.