Search code examples
vbacompatibility32bit-64bitlong-longvba7

compatibility 32bit-excel and 64-bit excel (office 365)


I am not experienced at vba so thank you for understanding.

I tested some old macros in office 365, previously I worked with excel 2016.

I read that some macros might not work properly because of the Long variable declaration. - As I understand correctly Long has 4bit and LongLong has 8bit. There is also sth like ►LongPtr which has 4bit-when other than VBA7 and 8bit-in VBA7.

My question is as follows: how it is possible that in excel365 I can still use a normal Long variable?

enter image description here


Solution

  • Long datatype isn't dead

    I read that some macros might not work properly because of the Long variable declaration.

    What you are probably referring to is that using API functions (API - Application Programming Interface) you have to take care of the different environments. These system functions do demand LongPtr types for for pointers to a → handle or → memory location (note the special PtrSafe prefix!).

    My question is as follows: how it is possible that in excel365 I can still use normal Long variable?

    A VBA procedure, contrary to cited API functions isn't forced to "prohibit" a Long datatype for a variable, just as little as you will be forced to do without Integer (though btw internally VBA prefers Long integers).

    Further notes to LongPtr declarations

    As a window handle is declared as LongPtr in Office 2010 or higher and as Long in versions before, it was necessary to differentiate between the different versions by conditional compile constants (#If VBA7 Then .. #End If) , for instance

    #If VBA7 Then              ' Office 2010 or higher
        Private Declare PtrSafe Function FindWindow Lib "User32" Alias "FindWindowA" _
               (ByVal lpClassName As String, _
                ByVal lpWindowName As String) _
        As LongPtr  
    #Else
        Private Declare Function FindWindow Lib "User32" _
            Alias "FindWindowA" _
           (ByVal lpClassName As String, _
            ByVal lpWindowName As String) As Long
    #End If
    

    Note that some API functions need to use also a conditional Win64 constant to identify actually installed 64bit Office systems; I mentioned already that frequently Office is installed as 32bit by default.

    LongPtr, however is not a true data type because it transforms to the right datatype depending on the actual 32/64-bit environment.

    Note that 64-bit systems can be installed either as 32-bit office or 64 bit office. LongPtr enables writing portable code that can run in both 32-bit and 64-bit environments.

    Hint: Take care to declare assigned API variables as well by the appropriate datatype. If you differentiate between versions via conditional compile constants, you have to do so with the referring variables within your own procedures, too.

    Related links

    Further recommended readings (thx @GSerg :-)

    Citing @GSerg in the following posts:

    "By adding PtrSafe to a function declaration, you promise to the compiler that you have put LongPtr in all places where it needs to be, and nowhere else."

    "LongPtr is a pointer-sized integer. It must be used for things that have the same size as a pointer."

    "Long exists in all versions and means the same thing in all versions (32-bit integer). You should not change it to LongPtr for the sake of it. You should only use LongPtr for pointers or pointer-sized data types."