Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Sage SDO Byte data type

Status
Not open for further replies.

JohnDA

Programmer
Aug 13, 2014
6
GB
thread184-741224
Following from the above closed thread.....
I am trying to read from sage dataobjects, I can read back most fields with data type such as string, numberic, logical etc, but any fields with data type 'byte' (As defined by Sage) result in 'function, argument, datatype or count invalid'

the following works fine as they return string and date values
?oInvoice.fields.item(23).value
?oInvoice.fields.item(25).value

but this causes the error message
?oInvoice.fields.item(24).value

although writing to this property does not error and writes back into sage correctly
oInvoice.fields.item(24).value=1


It seems FoxPro does not understand the datatype when reading

Is there any way of resolving this?

 
Welcome to the forum, John. This could be a tough problem to crack. We didn't solve it ten years ago, so we might not be able to solve it today.

I assume you have tried the various suggestions in the thread you referenced. It would be interesting to know the following:

1. What happens if you do this: [tt]?TRANSFORM(oInvoice.fields.item(24).value)[/tt] or this: ?[tt]VARTYPE(oInvoice.fields.item(24).value)[/tt] ?

2. Have you tried suspending the program at the point of the error, and then looking at [tt]oInvoice.fields.item(24).value[/tt] in the debugger's Watch window?

3. Does [tt]?oInvoice.fields.item(24)[/tt] give an error? (I would expect it to display [tt](Object)[/tt].)

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
It's always luck, if something like OLEArray[index].property works. In case an OLE array or a colletion is processed you better first store the array element - i.e. item(24) - into a variable and then try to read properties, or you even use a FOREACH:

So What if you do:

Code:
oItem = oInvoice.fields.item(24)
? oItem.value

Code:
FOR EACH oField in oInvoice.fields FOXOBJECT
? oField.value
ENDFOR

VFP OLE indeed has some limitations with byte arrays. There is COMARRAY() to cope with some variants of byte arrays, but the OLE conversion of types is limited, you might have no luck with a single byte type. The VB VARIANT type is another difficulty of OLE types.

The FOXOBJECT of the FOREACH loop may help, as it's there to enforce oField to be a native VFP object, so the OLE objects of the oInvoice.fields are converted to VFP objects, but this may fail in the same manner as accessing just the VALUE property.

It's weird it works in write direction and not in read direction, but you moist probably can thank the other side of the OLE automation for retrieving the right type there, if you write.

If nothing works for reading the VALUE property, you will need to wrap accessing the byte fields with a VB library or anything else capable to cope with the byte type, then you can hand over a byte as a integer or char(1) value.

Bye, Olaf.
 
Hi Mike,

Thanks for the quick response

1. ?VARTYPE(oInvoice.fields.item(24).value) gives the error message 'function, argument, datatype or count invalid'

2. In the watch windows value="expression could not be evaluated" type = <blank>

3. Yes it returns (Object)
All other properties of the object work OK and produce a result
e.g. ?oInvoice.fields.item(24).type shows -6 (Sage 'byte' data type)
?oInvoice.fields.item(24).description shows "currency"

It's a real shame, as all the other sage SDO objects, properties and methods work great....I can post invoices, Purchase orders, stock etc fine, but can't read anything with a 'byte' data type....It seems sage use this data type almost instead of a logical type as it's normally used as a flag (e.g. invoice printed 0 or 1)

I guess the data type is not recognised by FoxPro, but would have thought there was some way of getting the information? Any further help would be most appreciated as I have developed quite a large integration app for my customer.

Regards

John
 
John, unfortunately that doesn't take us any further forward.

This is a bit of a long shot, but are there any other properties of [tt]oInvoice.fields.item(24)[/tt] that might tell you the value? The reason I mention it is that VFP's native textboxes have both a Text and a Value property, both of which can be used to derive the value. There's no reason for the Sage object to also have two such properties, but it might be worth a quick check.

Failing that, I think the most promising thing to try next is Olaf's idea of using FOREACH with FOXOBJECT. Try running the second chunk of code he showed in his post. If that doesn't produce the error, it would be worth exploring it further.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Hi,

Thanks for the advise

have tried:
FOR EACH oField in oInvoice.fields FOXOBJECT
? oField.value
ENDFOR

produces a list of values then it errors when it gets to the byte type field

I've also tried all the properties of the object, but none reveal the value

I guess I'm going to have to wrap this with VB.... Is it possible to pass a reference to the object i.e. oInvoice.fields into VB, then VB return the value? It would be a large undertaking to wrap the whole of the Sage object in VB.

John
 
Well you won't be able to pass a reference to [tt]oInvoice.fields.item(24).value[/tt], as that will (I assume) give the same error (but it's worth a try). But, based on your answer to my third question above, you should be able to pass [tt]oInvoice.fields.item(24)[/tt]. Then, once you are in VB, you should be able to extract the Value property and return it as a string or number.

To pass the reference, just place it in parentheses in your function call in the usual way.

Mike



__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Thanks Mike, I'll dust off my VB hat and give it a go

John
 
I would pass over oInvoice to a VB library, nothing more specific. I think (but am not sure) any language will simply store a memory address as pointer to the COM object, so that would go unchanged from the original object over VFP to the VB wrapper, but in fact I thought of wrapping the original OLE server with VB and not use it in VFP at all.

You might make use of VB.NET and the wwDotnet Bridge and in the end automate SDO again in VFP, just not created in VFP, but in .NET. That means instead of doing o = CreateObject("SDOEngine") you'd do loBridge.CreateInstance("SDOEngineWrapper") or whatever you call your .NET wrapper class and then use it as usual in VFP, just now the .NET runtime is doing the OLE automation work instead of VFP, VFP in turn is using the wwDotnetBridge ClrHost.dll that is the core bridge from VFP over to the .NET CLR.

Bye, Olaf.
 
Thanks Mike and Olaf

RESOLVED!!!!

I now have this working with the following code (As crude as it may be)

LOCAL oVBS as MSScriptControl.ScriptControl, lcScript
oVBS=CREATEOBJECT('MSScriptControl.ScriptControl')
oVBS.Language="vbscript"
lcScript="function getval(object)"+CHR(13)+"getval = chr(object.value)"+CHR(13)+"end function"+CHR(13)
oVBS.AddCode(lcScript)
oInvoiceItem=oInvoice.fields.item(24)
?ASC(oVBS.Run("getval",@oInvoiceItem))

Note:
I couldn't pass oInvoice.fields.item(24) to the script, but putting this object into oInvoiceItem worked fine

without converting to character in VBS, the result returned a value that produced the original error message, but converting to character in VBS then back into a value in VFP works perfectly.

If I write a value into the object, the same value now reads back...So

oInvoiceItem=oInvoice.fields.item(24).value=22
?ASC(oVBS.Run("getval",@oInvoiceItem)) returns 22

This has really got me out of a hole....So many thanks

 
You could try ASC(oVBS.Run("getval",oInvoice.fields.item(24)))
An @ for passing a variable by reference a) only works with Variables, not with expressions. b) is not needed at all for objects, objects are always passed by reference, no matter if with or without @.

Anyway, it works. Nice. Good to know as the effort for vbscript of course is even less than writing a wrapper.

Bye, Olaf.
 
Delghted you got it working, John. A neat solution.

You said: "I couldn't pass oInvoice.fields.item(24) to the script, but putting this object into oInvoiceItem worked fine."

I should have realised that. VB subscripting works differently from VFP. Even if you could have passed the subscript like that, you might have got the wrong result - possibly because subscripting in VB is zero-based (at least, I think it is).

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Mike, I guess John tried @oInvoice.fields.item(24), but oInvoice.fields.item(24) should work, no matter how VB adresses arrays, this expression is evaluated by VFP, resulting in the object, which is then passed in.

Bye, Olaf.
 
Yes you are correct Olaf,

LOCAL oVBS as MSScriptControl.ScriptControl, lcScript
oVBS=CREATEOBJECT('MSScriptControl.ScriptControl')
oVBS.Language="vbscript"
lcScript="function getval(object)"+CHR(13)+"getval = chr(object.value)"+CHR(13)+"end function"+CHR(13)
oVBS.AddCode(lcScript)
?ASC(oVBS.Run("getvaloInvoice.fields.item(24)))

Works fine and removes a line of code

John
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top