Search code examples
vbams-wordboolean-operations

VBA: Why would the Not operator stop working?


This has me utterly baffled.

Sub testChangeBoolean()
  Dim X As Boolean       ' default value is False
  X = True               ' X is now True
  X = Not X              ' X is back to False
End Sub

But I'm trying to toggle the .FitText property in a table cell (in Word). .FitText starts as True.

If I assign it to X:

Sub testChangeBoolean()
  Dim X As Boolean                  ' again, default is False
  X = Selection.Cells(1).FitText    ' does set X to True
  X = Not X                         ' X is still True!
End Sub

I just don't understand what I'm doing wrong.


Solution

  • I believe the explanation has to do with how older programming languages (WordBasic and early VBA) stored the integer values of True and False. In those days, True = -1 and False = 0.

    Newer programming languages still use 0 for False, but 1 for True.

    The majority of Word's Boolean type properties continue to use -1 for True (Font.Bold, for example), which has been cause for confusion and frustration for programmers working with the Interop in newer languages. So, at some point, some developers at Microsoft decided to use the new way and assigned the integer value of 1 to True for some new functionality. Such as FitText.

    Considering the following code sample, where X is of type Boolean and y of type Integer:

    • If FitText is True, the integer value is 1
    • If reversing the values, using Not shows that the Boolean remains "True" because its integer value is not 0, it's -2
    • Setting the integer value directly to True gives -1

    This is confusing, indeed, but does explain why Not is not giving the expected result.

    Sub testChangeBoolean()
      Dim X As Boolean                  ' again, default is False
      Dim Y As Integer
      X = Selection.Cells(1).FitText    ' does set X to True
      Y = Selection.Cells(1).FitText
      Debug.Print X, Y                  ' result: True    1
      X = Not X                         ' X is still True!
      Y = Not Y
      Debug.Print X, Y                  ' result: True   -2
      X = False
      Y = True
      Debug.Print X, Y                  ' result: False  -1
    End Sub