|
Excel 5 has two "idiosyncrasies" with its DDERequest()
function. The first is that the DDERequest() function always
returns a variable with the data type "Variant Array".For
some unknown reason the DDERequest function in Excel expects
to receive a Tab delimited array of data. In fact, if the
data from the Wedge were tab delimited, Excel would automatically
parse it and fill up a Variant Array such that each tab delimited
data item would be stored in successive array elements. Typically,
data from most instruments is not tab delimited therefore
when you perform a DDERequest to the Wedge from Excel you
end up with a Variant Array variable with only a single element
(element 1) containing all the data from the field in the
Wedge that you are requesting the data from.
Excel will let you assign a Variant Array to a cell in a
spreadsheet however if you try to perform string functions
on a Variant Array, Excel generates an "Invalid Data
Type" error. The Variant Array must be converted to
a string data type before it can be used in a string function.
This problem is easily overcome by simply assigning the Variant
Array element 1 to a string. The following code fragment
uses the DDERequest function to return a Variant Array and
then uses an assignment statement to convert element 1 of
the Array to a string.
| |
DDEChannel = DDEInitiate("WinWedge",
"Com2")
DDEVariantArray
= Application.DDERequest(DDEChannel, "Field(1)")
DDETerminate DDEChannel
'
assign Array element 1 to a String variable
StringVariable$ = DDEVariantArray(1)
|
The second problem is that the DDERequest() function
can only return string data that is less than 255 bytes unless
the string is delimited with tabs (see the following section "Advanced
Excel Tricks" pg. 93). If you try to DDERequest() a
data string that is longer than 255 bytes, Excel truncates
the data and you lose anything after the 255th byte.
The following subroutine shows how to get around both of
the problems described above as well as how to get around
the 40 field limit in the Software Wedge. To get past the
40 field limit in the Wedge, instead of using the parsing
capabilities of the Wedge, we will use our own parsing routine
written in Excel VBA. To do this we first have to get all
the data from the device into a single string variable in
Excel. This is where the problems in Excel catch up to us,
especially when the total length of the data stream could
be more than 255 bytes.
The following example shows how to configure the Wedge and
Excel to deal with a situation where a device transmits a
data record containing over 40 data fields that are delimited
with commas and terminated with a carriage return. The total
length of the data could also be over 255 bytes. If Excel
were capable of pulling in over 255 bytes with the DDERequest
function, then all we would have to do is define the "End
of Record Event" in the Wedge as "Carriage Return
or CrLf Received" and then define the structure of the
data records as "Single Field". Finally, we would
use a VBA macro to parse the string after we pass it to Excel.
Because the data string could be over 255 bytes long, we
have to break it into pieces before passing it to Excel and
then put it back together again in our VBA macro.
The way to do this is to again select "Carriage Return
or CrLf Received" as the "End of Record Event" in
the Wedge and then select "Multiple Fixed Length Data
Fields" as the "Record Structure". Finally,
define several data fields with all their field lengths set
to 250 bytes. You need to define enough 250 byte data fields
so that the largest data record from the device will fit
in all the fields defined in the Wedge. For example if the
largest record transmitted by the device is 1125 bytes, then
you would need to define five 250 byte data fields. Make
sure that the Wedge is in DDE Server mode and after the very
last data field that you define, enter: [RUN("NewGetSWData")] as
the "Field Postamble DDE Command".
The above command will cause Excel to run a subroutine named "NewGetSWData" after
each complete data record is received by the Wedge.
Note: Be sure not to apply any Filters to any of the data
fields that you define in the Wedge.
The following subroutine performs the job of pulling the
data from the Wedge and then putting it back together into
one long string. Finally the subroutine parses the data into
individual data fields and plugs each field into separate
cells in a row of the spreadsheet.
| |
Sub NewGetSWData() '
this sub is run by the Wedge after each data
record is received
Static R
As Long, C As Long
' R & C point to the Row and
Column where the data will go
If R = 0 Then R = 1: C = 1 '
make sure neither R or C is zero
Chan = DDEInitiate("WinWedge", "Com2")
' assume that there are 5 data fields
defined - change to more or less if necessary
Field1 = Application.DDERequest(Chan, "Field(1)") ' get field 1
Field2 = Application.DDERequest(Chan, "Field(2)") ' get field 2
Field3 = Application.DDERequest(Chan, "Field(3)") ' get field 3
Field4
= Application.DDERequest(Chan, "Field(4)") ' get field 4
Field5
= Application.DDERequest(Chan, "Field(5)") ' get field 5
DDETerminate
Chan ' kill the link
MyVar$
= Field1(1) & Field2(1) & Field3(1) & Field4(1) & Field5(1) & ","
' Convert each variant array to a string,
concatenate them all together and
' add a final comma delimiter for the following parsing routine. The following
' code parses the string MyVar$ by searching for commas and placing each
' delimited field in a separate row
StartPos
= 1 ' starting
position in the string - start at 1st byte
While
StartPos < Len(MyVar$) ' scan until we reach the end of the string
DelimPos
= InStr(StartPos, MyVar$, ",") ' find the next comma delimiter
DataPoint$
= Mid$(MyVar$, StartPos, DelimPos - StartPos)
' pull out a data point between the starting
position and the position of the delimiter
StartPos
= DelimPos + 1 ' update the starting position (skip
over the delimiter)
Sheets("Sheet1").Cells(R,
C).Value = DataPoint$ ' save the current data point
R
= R + 1 ' point R to the next row down for the next data point
Wend ' go get the next point
R
= 1 ' point R back to row 1
C
= C + 1 ' increment
C - move to the right one column for the next set of data
End
Sub |
Related Links
Reading
large arrays of data into Excel
Excel
DDERequest Function Issues |