Page 1 of 1

COM: VBA to VB (SafeArray related question)

Posted: Mon Sep 10, 2018 5:13 pm
by Yuri_D
Hello!

Can you help me to translate this VBA code to PB please?

Code: Select all

Function FieldType(obj As Object, label As String) As String
    FieldType = "string" 'default
    Dim f As Integer
    For f = LBound(obj.fields) To UBound(obj.fields)
      Dim lc: lc = LCase(label)
        If (lc = LCase(obj.fields(f).label) Or lc = LCase(obj.fields(f).name)) Then
            FieldType = obj.fields(f).Type
            Exit For
        End If
    Next f
'  5.05  If (FieldType = "") Then
'        Error "invalid label -->" & label
'    End If
End Function
When I'm using a SafeArray for obj.Fields it returns only the field Values but it contains field Labels, Names Types etc. which I need to retrieve.

Re: COM: VBA to VB (SafeArray related question)

Posted: Tue Sep 11, 2018 4:49 pm
by Yuri_D
:cry:
Nobody knows?
Looks like this Safearray is uni-dimensional, each element has \vt = 9 (Dispatch) and being converted by VT_STR(*Var.Variant) it returns the \Value parameter but Excel can return \Name, \Label and \Type as well.
No idea how to do the same on PB... :oops: :oops: :oops:

Re: COM: VBA to VB (SafeArray related question)

Posted: Tue Sep 11, 2018 4:55 pm
by mk-soft
Show to SafeArray...

Perhaps help this... Link: viewtopic.php?f=14&t=40150

Re: COM: VBA to VB (SafeArray related question)

Posted: Tue Sep 11, 2018 5:01 pm
by Yuri_D
Hi mk-soft,
Thanks, I'm using this add-in but it doesn't help in this case(
I think that iDispatch can point to another array but I have no enough knowledge to proof it and to extract the data

Re: COM: VBA to VB (SafeArray related question)

Posted: Tue Sep 11, 2018 5:51 pm
by skywalk

Re: COM: VBA to VB (SafeArray related question)

Posted: Tue Sep 11, 2018 7:15 pm
by Yuri_D
Hi skywalk,

Thanks, I learned a little bit more and now at least I understand the meaning of fields
* SafeArray *
cDim: 1
cbElements: 16
* rgsabound *
cElements: 78
lLbound: 0

But the problem is that it is an array of objects... and here I'm losing the way :oops:
I tried to wrap it by COMate_WrapCOMObject() but COMate crashes on this so looks I do something wrong... totally... :oops:

Re: COM: VBA to VB (SafeArray related question)

Posted: Tue Sep 11, 2018 10:32 pm
by mk-soft
I think the Object its Array Of Variant

Code: Select all

; Not Test

CompilerIf Defined(pData, #PB_Structure) = 0
  Structure pData
    StructureUnion
      llVal.q[0]
      lVal.l[0]
      bVal.b[0]
      iVal.w[0]
      fltVal.f[0]
      dblVal.d[0]
      boolVal.w[0]
      bool.w[0]
      scode.l[0]
      cyVal.l[0]
      date.d[0]
      bstrVal.i[0]
      varVal.VARIANT[0] ; Added ?
      Value.VARIANT[0] ; Added ?
      *punkVal.IUnknown[0]
      *pdispVal.IDispatch[0]
      *parray[0]
      *pbVal.BYTE[0]
      *piVal.WORD[0]
      *plVal.LONG[0]
      *pllVal.QUAD[0]
      *pfltVal.FLOAT[0]
      *pdblVal.DOUBLE[0]
      *pboolVal.LONG[0]
      *pbool.LONG[0]
      *pscode.LONG[0]
      *pcyVal.LONG[0]
      *pdate.DOUBLE[0]
      *pbstrVal.INTEGER[0]
      *ppunkVal.INTEGER[0]
      *ppdispVal.INTEGER[0]
      *pparray.INTEGER[0]
      *pvarVal.VARIANT[0]
      *byref[0]
      cVal.b[0]
      uiVal.w[0]
      ulVal.l[0]
      ullVal.q[0]
      intVal.l[0]
      uintVal.l[0]
      *pdecVal.LONG[0]
      *pcVal.BYTE[0]
      *puiVal.WORD[0]
      *pulVal.LONG[0]
      *pullVal.QUAD[0]
      *pintVal.LONG[0]
      *puintVal.LONG[0]
      decVal.l[0]
      brecord.VARIANT_BRECORD[0]
    EndStructureUnion
  EndStructure
CompilerEndIf

Global.variant var.Variant, *obj
Global *psa.SAFEARRAY

*obj = var
If *obj\vt = (#VT_ARRAY | #VT_VARIANT)
  Debug "Is Array of Variant"
  *psa = *obj\parray
  For i = 0 To *psa\dummyrgsabound\cElements - 1
    If *psa\pvData\Value[i]\vt = #VT_DISPATCH
      Debug "Is Field Object"
      *Field.IDispatch = *psa\pvData\Value[i]\pdispVal
    EndIf
  Next
EndIf


Re: COM: VBA to VB (SafeArray related question)

Posted: Wed Sep 12, 2018 7:42 am
by Yuri_D
Hi mk-soft,

So many rows of code and only one which solved my problem))
Protected.i _iEntity, _iLBound, _iUBound
Protected.COMateObject _objField
Protected.SAFEARRAY *saEntity
Protected.IDispatch *idField

*saEntity = VT_ARRAY( _obj\GetVariantProperty( "Fields")) ; "Fields" VARIANT type: VT_ARRAY | VT_VARIANT
_iLBound = saLBound( *saEntity)
_iUBound = saUBound( *saEntity)

For _iEntity = _iLBound To _iUBound

*idField = *saEntity\pvData\Value[_iEntity]\pdispVal

_objField = COMate_WrapCOMObject( *idField)
If _objField
Debug _objField\GetStringProperty( "Name")
Debug _objField\GetStringProperty( "Value")
Debug _objField\GetStringProperty( "Type")
_objField\Release()
EndIf
Next
saFreeSafeArray( *saEntity)
Thank you so much!