Announcement

Collapse
No announcement yet.

Byte to variant requires AS?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Byte to variant requires AS?

    Does assigning a byte to a variant require using AS or is this an error in my code?
    Code:
    #DIM ALL
    FUNCTION PBMAIN AS LONG
     LOCAL b AS BYTE
     LOCAL v AS VARIANT
     v = b
     ? STR$(VARIANTVT(v)) 'wrong, 3 returned,long integer
    
     v = b AS BYTE '<------ AS works
     ? STR$(VARIANTVT(v)) 'correct, 17 byte unsigned
    END FUNCTION
    v = b? 'is also wrong, 3 returned, long integer

    #2
    from Help for LET statement (with Variants) -

    LET VrntVar= expression [AS vartype]

    "The numeric or string expression is evaluated, and the result is stored in the variant variable. PowerBASIC will choose an appropriate numeric or string data type to use. However, you can specify a preferred format by adding an optional AS vartype clause. This can be BYTE, WORD, DWORD, INTEGER, LONG, QUAD, SINGLE, DOUBLE, CURRENCY, or WSTRING. Strings in a variant are always stored in wide Unicode, regardless of whether you add AS WSTRING or not. PowerBASIC handles the conversion automatically, if it is needed. . . ." (bold added)

    Apparently PB picks type unless you force with AS

    Cheers,
    Dale

    Comment


      #3
      If you are not comfy with allowing PB to make the assignment of the variant datatype, or if PB does not support the variant datatype required*, here is how to do it..

      Create VT_DATE variant Datatype 9-14-09

      This function may also come in handy..

      Get VARIANTVT literal


      * I ran into this when I needed both VT_DATE and VT_BOOL types, which are not supported by PB.. and on the "read me" types, the VARIANT(type specifier) does not read these or the VT_DECIMAL type.

      FWIW, VT_DATE is needed to pass parameters to prepared SQL queries; VT_BOOL is required by some of the MQ interfaces (PB COM browser creates these as "LONG") and VT_DECIMAL is returned by some SQL queries from Oracle DBs (maybe more but Oracle for sure).
      Michael Mattias
      Tal Systems (retired)
      Port Washington WI USA
      [email protected]
      http://www.talsystems.com

      Comment


        #4
        Thanks Michael for all the return values, but BYTE still returns 3 instead of 17 using VARIANTVT.
        Code:
        #DIM ALL
        FUNCTION PBMAIN AS LONG
         LOCAL b  AS BYTE
         LOCAL vW AS VARIANT
         LOCAL iType AS LONG
         vW = b
         iType =   VARIANTVT(vW)
         ? variantTypeLiteral(iType)
        END FUNCTION
        
        FUNCTION VariantTypeLiteral ( BYVAL iType AS LONG) AS STRING
        
            LOCAL X  AS LONG, W AS STRING
        
            ' mask off the array, BYREF and vector bits , handle separately
             X = iType AND NOT(%VT_ARRAY OR %VT_BYREF OR %VT_VECTOR)
        
            SELECT CASE AS LONG X
                  CASE   %VT_EMPTY      :  W = "VT_EMPTY"      '  0 no value of any kind
                  CASE   %VT_NULL       :  W = "VT_NULL"       '  1 null (eg from database)
                  CASE   %VT_I2         :  W = "VT_I2"         '  2 INTEGER
                  CASE   %VT_I4         :  W = "VT_I4"         '  3 LONG
                  CASE   %VT_R4         :  W = "VT_R4"         '  4 single
                  CASE   %VT_R8         :  W =  "VT_R8"        '  5 double
                  CASE   %VT_CY         :  W = "VT_CY"         '  6 Currency
                  CASE   %VT_DATE       :  W = "VT_DATE"       '  7 date (a double =   ccyymmdd.hhmmsstt)
                  CASE   %VT_BSTR       :  W = "VT_BSTR"       '  8 dynamic string
                  CASE   %VT_DISPATCH   :  W = "VT_DISPATCH"   '  9 IDispatch
                  CASE   %VT_ERROR      :  W =  "VT_ERROR"     ' 10 errror (eg DISP_E_PARAMNOTFOUND)
                  CASE   %VT_BOOL       :  W = "VT_BOOL"       ' 11 Boolean
                  CASE   %VT_VARIANT    :  W =  "VT_VARIANT"   ' 12 Variant
                  CASE   %VT_UNKNOWN    :  W = "VT_UNKNOWN"    ' 13  IUnknown (interface)
                  CASE   %VT_DECIMAL    :  W = "VT_DECIMAL"    ' 14   decimal 16-byte fixed point use VarBstrfromDec to convert.
                  CASE   %VT_I1         :  W  = "VT_I1"        ' 16  byte (signed)
                  CASE   %VT_UI1        :  W = "VT_UI1"        ' 17  byte (unsigned)
                  CASE   %VT_UI2        :  W = "VT_UI2"        ' 18  WORD  (unsigned)
                  CASE   %VT_UI4        :  W = "VT_UI4"        ' 19  DWORD (unsigned)
                  CASE   %VT_I8         :  W = "VT_I8"         ' 20   QUAD (signed)
                  CASE   %VT_UI8        :  W = "VT_UI8"        ' 21  QUAD (unsigned) (LARGE_UINT)
                  CASE   %VT_INT        :  W = "VT_INT"        ' 22  integer (signed)
                  CASE   %VT_UINT       :  W = "VT_UINT"       ' 23  WORDr (unsigned)
                  CASE   %VT_VOID       :  W = "VT_VOID"       ' 24  C-style VOID (???)
                  CASE   %VT_HRESULT    :  W = "VT_HRESULT"    ' 25  COM result code
                  CASE   %VT_PTR        :  W = "VT_PTR"        ' 26  Pointer
                  CASE   %VT_SAFEARRAY  :  W = "VT_SAFEARRAY"  ' 27  VB array
                  CASE   %VT_CARRAY     :  W = "VT_VCARRAY"    ' 28  C-style array
                  CASE   %VT_USERDEFINED:  W = "VT_USERDEFINED"' 29  user-defined type
                  CASE   %VT_LPSTR     :  W = "VT_LPSTR"       ' 30  (ptr to)  ANSI STRING (ASCIIZ PTR)
                  CASE   %VT_LPWSTR      :  W = "VT_LPWSTR"    ' 31  (ptr to)  Unicode string
                  CASE   %VT_FILETIME     :  W = "VT_FILETIME  ' 64  FILETIME structure
                  CASE   %VT_BLOB       :  W = "VT_BLOB"      '  64  arbitrary block of memory
                  CASE   %VT_STREAM     :  W = "VT_STREAM"     ' 66  byte stream
                  CASE   %VT_STORAGE   :  W = "VT_STORAGE"     ' 67  Name of the storage object
                  CASE   %VT_STREAMED_OBJECT: :  W = "VT_STREAMED_OBJECT"  ' 68 A stream that contains an object
                  CASE   %VT_STORED_OBJECT: :  W = "VT_STORED_OBJECT"  ' 69  A storage object
                  CASE   %VT_BLOB_OBJECT: :  W = "VT_BLOB_OBJECT"  ' 70 A block of memory that represents an object
                  CASE   %VT_CF           :  W = "VT_CF"        ' 71 A clipboard format
                  CASE   %VT_CLSID        :  W = "VT_CLSID"        ' 72 Class ID
                  CASE   ELSE             :  W = USING$ ("Unrecognized &", HEX$(X,2))
            END SELECT
        
            ' add literals for optional bits in an order which makes sense when reading them
            IF ISTRUE (iType AND %VT_BYREF) THEN
                W  =   W & " BYREF"
            END IF
            IF ISTRUE (iType AND %VT_VECTOR) THEN
                  W = W & " VECTOR (leading count)"
            END IF
            IF ISTRUE (Itype AND %VT_ARRAY) THEN
                  W =  W & " ARRAY
            END IF
        
            FUNCTION = W
        
        END FUNCTION'

        Comment


          #5
          . . . , but BYTE still returns 3 instead of 17 using VARIANTVT.
          Because you're still not using AS BYTE

          like
          vW = b AS BYTE
          in your code. Not to be confused with
          LOCAL b AS BYTE
          Dale

          Comment


            #6
            Doh

            And it now returns the correct result with Michaels routine.
            W = "17 VT_UI1" ' 17 byte (unsigned)

            Comment

            Working...
            X
            😀
            🥰
            🤢
            😎
            😡
            👍
            👎