Kamis, 28 Agustus 2014

RE: [MS_AccessPros] Conditional API declaration

 

Hi Crystal

Sorry, I didn't explain it clearly enough.  When we are early binding, we use the constant olMailItem which is defined in the referenced object library.  It happens to have the value zero (which we can discover by typing ?olMailItem in the immediate window). 

When we remove the reference and turn off early binding, the constant is no longer defined, so we need to define it ourselves – hence the Const olMailItem = 0 in the #Else block.  However, if we got this wrong, and defined it as 1 instead, our code would not behave as expected because CreateItem would create a different sort of item, not a mail message.

If we put Debug.Assert olMailItem = 1 in the early binding block, then we will get a runtime error when that line is executed, because the value of olMailItem is not 1, but 0.  The Debug.Assert then serves to verify that out Const declarations are correct before we remove the reference.

The general form is:

#If EarlyBinding Then
    Debug.Assert <constantname> = <value>
#Else
    Const <constantname> = <value>
#End If

I hope that's clearer now :-)

All the best
Graham

 

From: MS_Access_Professionals@yahoogroups.com [mailto:MS_Access_Professionals@yahoogroups.com]
Sent: Friday, 29 August 2014 15:08
To: MS_Access_Professionals@yahoogroups.com
Subject: Re: [MS_AccessPros] Conditional API declaration

 

 

Hi Graham,

 

very nice, thanks

 

can you explain why you would use Debug.Assert? What is the advantage? or disadvantage if you do not?

 

thanks, Graham

 

 

Warm Regards,

Crystal

 

Popup Calendar that works with Access 2007 and above
Popup Calendar for Access 2007 and above

 

 

 

image

 

 

 

 

 

Popup Calendar for Access 2007 and above

download:uploads/84/PopupCalendar_Crys...

Preview by Yahoo

 

 

 *

   (: have an awesome day :)

 *

 

 

 

 

On Thursday, August 28, 2014 5:20 PM, "'Graham Mandeno' graham@mandeno.com [MS_Access_Professionals]" <MS_Access_Professionals@yahoogroups.com> wrote:

 

 

Thank you, Crystal!  From such a great teacher as you, that is indeed a fine compliment!  :-)

Yes, conditional compilation (CC) works very well for Dim statements – for example:

#If EarlyBinding_Outlook Then
Debug.Assert olMailItem = 0
Dim olkApp As Outlook.Application
Dim olkNS  As Outlook.NameSpace
Dim olkMsg As Outlook.MailItem
#Else
Dim Const olMailItem = 0
Dim olkApp As Object
Dim olkNS  As Object
Dim olkMsg As Object
#End If
  Set olkApp = CreateObject("Outlook.Application")
  Set olkNS = olkApp.GetNamespace("MAPI")
  Set olkMsg = olkApp.CreateItem(olMailItem)

The Debug.Assert statement verifies during development, when early binding is being used, that the value of the constant olMailItem is indeed 0.  Then we know that the Const statement in the #Else block will be correct when we remove the reference to the Outlook object library.

The constant, EarlyBinding_Outlook can be defined at the top of the module:

#Const EarlyBinding_Outlook = True

… in which case it only applies to that module, or it can be defined in the Project Properties dialog box, in which case it applies to the whole project.

And no, CC arguments can only be constants, not variables.  It makes no sense to change them at run-time, as they only affect the compilation.

Cheers,
Graham

From: MS_Access_Professionals@yahoogroups.com [mailto:MS_Access_Professionals@yahoogroups.com]
Sent: Friday, 29 August 2014 08:54
To:
MS_Access_Professionals@yahoogroups.com
Subject: Re: [MS_AccessPros] Conditional API declaration

 

 

Hi Graham,

 

you have such a gift for teaching

 

> "turn on and off early binding of object libraries."

great idea ... so it works on Dim statements too?  Tried defining them differently with a regular IF and that didn't work. 

 

hey, it is possible to set a dynamic value in the # stuff to conditionally execute something according to what is going on in VBA?  Or is that decided when it is compiled?

 

thanks, Graham

 

Warm Regards,

Crystal

 

 

 

 

 

 

 

 

uploads/84/Random_Picker_by_Crystal_120318__XLS.zipPick one or more random values from any column...

Preview by Yahoo

 

 

 *

   (: have an awesome day :)

 *

 

 

On Thursday, August 28, 2014 12:36 PM, "'Graham Mandeno' graham@mandeno.com [MS_Access_Professionals]" <MS_Access_Professionals@yahoogroups.com> wrote:

 

 

Hi Stuart

VBA7 is a built-in compiler constant which is used in a conditional compilation #If statement to determine the version of VBA which is compiling the code.  If VBA7 is True, then the version is 7.x (or later, but no later version exists yet) and the new syntactic elements that were introduced with Office 2010 are understood by the compiler.  In older versions, VBA7 is not defined (therefore it cannot be True) and this indicates that the programmer should not use the new features.

A conditional compilation #If statement differs from a traditional If statement in that if the compilation condition is not True, there is no requirement for syntactic correctness, while in a traditional If statement, all the code must be syntactically correct, even though it might never get to run.  This code, for example, will compile OK, even though it is gibberish to the compiler:

#If False Then
  This is not a comment but it makes no sense at all %$ > ???
#End If

You can also define your own compiler constants to turn bits of code on and off.  For example:

#Const Debugging = True
. . .
#If Debugging Then
    MsgBox "We made it to Point A"
#End If

I use them all the time to turn on and off early binding of object libraries.

Cheers,
Graham

 

From: MS_Access_Professionals@yahoogroups.com [mailto:MS_Access_Professionals@yahoogroups.com]
Sent: Friday, 29 August 2014 01:18
To:
MS_Access_Professionals@yahoogroups.com
Subject: Re: [MS_AccessPros] Conditional API declaration

 

 

Graham, what is "VBA7" exactly?   Is it a property of something?

 

Thanks, Stuart

 

On Wednesday, August 27, 2014 8:39 PM, "'Graham Mandeno' graham@mandeno.com [MS_Access_Professionals]" <MS_Access_Professionals@yahoogroups.com> wrote:

 

 

I stand humbled and corrected!  It was Office 2010, not 2007, which introduced VBA7 and 64-bit.  Sorry!

So maybe we're stuck with the dual declares for a bit longer :-)

Cheers,
Graham

 

From: MS_Access_Professionals@yahoogroups.com [mailto:MS_Access_Professionals@yahoogroups.com]
Sent: Thursday, 28 August 2014 09:55
To:
MS_Access_Professionals@yahoogroups.com
Subject: RE: [MS_AccessPros] Conditional API declaration

 

Hi Crystal

I changed the subject :)

The main point is that code for 64-bit VBA must include the PtrSafe qualifier in the Declare statement.  This is not required for 32-bit VBA, but its absence will prevent compilation on 64-bit.  It is, however, understood by both bit-ness of VBA7, so should be included in all Declares for VBA7 onward. (VBA7 is currently the latest version).

However, it is not understood on versions pre-VBA7 (pre-Office 2007) and will cause a compiler error.  This is why we need to include the #Else block with the old format of the declaration, so that the code will work in Access 2003 and earlier.  I guess that as pre-2007 versions of Access disappear, the need for the conditional Declare will also largely disappear, but I don't see that happening soon.  (Look at Tom Wickerath and Boeing, for example!)

By the way, PtrSafe doesn't actually do anything!  It's just a way to make sure that the programmer has read the Terms & Conditions and at least made an attempt to ensure the code is 64-bit compatible :-)

The other main difference is in variables which are pointers (i.e. addresses of locations in memory).  32-bit code addresses memory with 32-bit pointers, which can be stored in a Long variable, but 64-bit code uses 64-bit pointers which obviously don't fit.  VBA has therefore introduced a new data type, LongPtr, which is a Long in a 32-bit code base, and a new 64-bit integer data type LongLong in 64-bit code.  Using Long instead of LongPtr will work fine in 32-bit, and will compile OK in 64-bit but will crash and burn at runtime because the API will be reading and writing 64-bit values where only 32 bits have been allocated for storage.

A very few API functions have versions that actually use 64-bit integers (not pointers) and for these the arguments need to be declared as LongLong.  VBA does not understand LongLong in 32 bit, so there is another compiler constant Win64 which is True if the code is running in 64-bit mode.  I have seen code where programmers have used #If Win64 instead of #If VBA7 for the two types of declaration.  While this will work OK, it is not technically correct, because VBA7 is designed to understand both types of pointer.  Note that Win64 indicates the bit-ness of the office application code, not the bit-ness of the Windows operating system it is running on (as is stated in some documentation).

Hope this clarifies things a little :-)

Cheers,
Graham

From: MS_Access_Professionals@yahoogroups.com [mailto:MS_Access_Professionals@yahoogroups.com]
Sent: Thursday, 28 August 2014 00:12
To:
MS_Access_Professionals@yahoogroups.com
Subject: Re: [MS_AccessPros] widths and heights

 

 

Hi Graham,  right away, I see this:

#If VBA7 Then
   ' use LongPtr
#Else
   'As Long
#End if

what are other changes that you make?

thanks!

 

 

Warm Regards,

Crystal

 

Contacts database in Access

Contacts_070604 ... being updated ~ hopefully post something new in a few months

 

 

 

 

 

__._,_.___

Posted by: "Graham Mandeno" <graham@mandeno.com>
Reply via web post Reply to sender Reply to group Start a New Topic Messages in this topic (9)

.

__,_._,___

Tidak ada komentar:

Posting Komentar