19.4.3. Sample Excel Macros for Arrays

The following macros represent the entire macro set for a simple test spreadsheet that reads and writes a single array point in the DataHub instance. The two functions GetData and PutData can be attached to buttons on a spreadsheet for easy testing. The PutData subroutine contains two alternative representations of the source range, one of which is commented out in the macro.

Sub GetDataArray(Channel As Integer, SheetName As String, DataPoint _
				As String, StartRow As Integer, StartCol As Integer)
    Dim NRows As Integer, NCols As Integer
    
    ' This sub performs a DDERequest for DataPoint in the DDE Channel
    ' and reads in a tab delimited array with carriage returns at the 
    ' end of each line. It then fills a range of cells with the data. 
    ' The native format for Excel data is tab delimited text with a
    ' carriage return at the end of each row of data. If we assign 
    ' this type of data to a range of cells using the FormulaArray 
    ' function, Excel automatically parses the data and fills it into 
    ' the specified range.  The real trick here is to ensure that the
    ' range is the same size as the incoming data, so we do not have 
    ' to know the size a priori.
    
    ' request DataPoint from Channel
    
    DataArray = DDERequest(chan, DataPoint)   
    
    ' find the upper row and column bounds for the variant array
    
    If StartCol = 0 Then StartCol = 1   ' Starting column where 
                                        ' data will go in our sheet
    If StartRow = 0 Then StartRow = 1   ' set the starting row
    NCols = 1                           ' set default number or 
                                        ' columns to 1
    On Error Resume Next                ' ignore errors (error occurs 
                                        ' if array has one dimension)
    
    ' get upper bound of the array columns
    ' the following line will generate an error if the array is only 
    ' a one dimensional array
    ' We just skip this, and use the default 1
    NCols = UBound(DataArray, 2)
    
    On Error GoTo 0                     ' allow errors
    NRows = UBound(DataArray, 1)        ' get upper bound of 
                                        ' array y dimension
    
    NRows = NRows + StartRow - 1        ' add offset from StartRow 
                                        ' - this is the ending row
    NCols = NCols + StartCol - 1        ' add offset from StartCol 
                                        ' - this is the ending col
    
    ' the following line fills up the cells in the range starting 
    ' in "StartCol:StartRow" to "Nrows:Ncols" with the data from 
    ' the variant array
    Sheets(SheetName).Range(Cells(StartRow, StartCol), _
    						Cells(NRows, NCols)) = DataArray
End Sub

Sub PutDataArray(Channel As Integer, SheetName As String, DataPoint _ 
				As String, StartRow As Integer, StartCol As Integer, _
				NRows As Integer, NCols As Integer)
    DDEPoke Channel, DataPoint, _ 
    		Sheets(SheetName).Range(Cells(StartRow, StartCol), _
            Cells(StartRow + NRows - 1, StartCol + NCols - 1))
End Sub
Sub PutDataRange(Channel As Integer, DataPoint As String, _
					DataRange As Range)
    DDEPoke Channel, DataPoint, DataRange
End Sub

Sub GetData()
'
'   This is a test function assigned to a button.  It reads a test 
'   point into an arbitrarily sized matrix starting at A10
'
    Dim chan As Integer
    chan = DDEInitiate("datahub", "default")
    GetDataArray chan, "Sheet1", "TestArray", 10, 1
    DDETerminate (chan)
End Sub

Sub PutData()
'
'   This is a test function assigned to a button.  It writes 
'   a 3 row x 5 column area of Sheet1 into a single data point 
'   in a DataHub instance.  You can use either PutDataArray or 
'   PutDataRange, depending on how you wish to specify the range.
'
    Dim chan As Integer
    chan = DDEInitiate("datahub", "default")
    'PutDataArray chan, "Sheet1", "TestArray", 1, 1, 3, 5
    PutDataRange chan, "TestArray", Sheets("Sheet1").Range("A1:E3")
    DDETerminate (chan)
End Sub