DIAdem

cancel
Showing results for 
Search instead for 
Did you mean: 

Import Excel data with Script not using STP

I am working with the following script to import a large amount of data into diadem to the perform analysis and reporting.  I cannot use the excel import wizard or the STP configuration files because the sheets will all be different.
 
The excel file I am working with has 42 worksheets with varying amounts of channels and channel lenghts.  When this excel file is created I used Named Ranges in excel to make is easy to find the information I need without having to search through cells.
 
The sub LoadGroups works perfectly.  It will create the correct groups in the data portal quickly.
 
The problem is in the LoadChannels routine.  I get a type mismatch error with this line (TempArray = .Range(NamesRange).Value) highlighted in red below.  I have this exact logic working in a VB6 application already.  The variable temparray is dimensioned as a variant, so I don't understand how there could be a type mismatch.
 
I have attached a reduced size excel sheet.  If you try to run the code you will have to change the FilePath to be the correct location.
 
I suspect it will be an easy fix, but I just can't see it.
 
Thanks for the help.
 
Wayne
 
 
 
'-------------------------------------------------------------------------------
'-- VBS script file
'-- Created on 02/23/2008 19:56:07
'-- Author: Wayne Yount
'-- Comment: Trial to import excel based results
'-------------------------------------------------------------------------------
Option Explicit  'Forces the explicit declaration of all the variables in a script.

Call DataDelAll   'clear all previous data
Dim FilePath
FilePath = "C:\Documents and Settings\Wayne Yount\Desktop\_path\fw586 results.xls"

call LoadGroups (FilePath)
call LoadChannels (FilePath)
 
 
sub LoadGroups (FilePath)
  Dim y,x,z,SheetName

  call ExcelCountSheets(FilePath)
  y = ExcelStat
  for x = 1 to ExcelSheetCount
      SheetName = ExcelSheets(x)
      SheetName = Ltrim(Rtrim(SheetName))
      z = instr(1,SheetName,"Sheet")
      If len(SheetName) = 6 and z = 0 then
         Call GroupCreate(SheetName)
      end if
  Next 'x
end sub
sub LoadChannels (FilePath)
  Dim a,b,c,d,f,grpindex,Frs,Channels,TempArray(),grpname,exRange
  Dim i,Excel, ExcelSheet, WorkBook, PropName, ErrNum
  Dim SheetNames(),NumSheets,NumChanNames,ChanNames(),NamesRange
  call ExcelCountSheets(FilePath)
  a = ExcelStat
  If a = 0 then
    ReDim SheetNames(ExcelSheetCount)
    For b = 1 to ExcelSheetCount
      SheetNames(b) = ltrim(rtrim(ExcelSheets(b)))
    Next 'b
  end if
 
  WorkBook = NameSplit(FilePath, "N") & ".XLS"
  On Error Resume Next
  Set Excel = CreateObject("Excel.Application") ' Start Excel via OLE
  ErrNum = Err.Number
  On Error Goto 0
  IF ErrNum <> 0 THEN Exit Sub
  Excel.Visible = true ' Don't hide Excel during debug so you can close it manually
  'Excel.ScreenUpdating = FALSE ' Disable screen refresh
  Excel.Workbooks.Open(FilePath) ' Open Excel File
  for c = 1 to ExcelSheetCount
    grpindex = groupindexget(SheetNames(c))
    if grpindex <> 0 then
      GroupDefaultSet(grpindex)
      NamesRange = SheetNames(c) & "!BodyRelativeChannelNames"
      Set ExcelSheet = Excel.Workbooks(WorkBook).Sheets(SheetNames(c))
      with ExcelSheet
        Frs = .Range(NamesRange).Rows.Count
        Channels = .Range(NamesRange).Columns.Count
        ReDim ChanNames(Channels-1)
        ReDim TempArray(Frs-1, Channels-1)
        TempArray = .Range(NamesRange).Value
        for d = 1 to Channels
          ChanNames(d-1) = TempArray(0,d-1)
        Next 'd
      end with
      for f = 1 to Channels
        Call ChnAlloc(ChanNames(f),1024)
      next 'f
    end if
  next 'c
  'FOR i = 1 TO 9
  '  Call GroupPropCreate(GroupIdx, "Prop" & i, DataTypeString)
  '  Call GroupPropSet(GroupIdx, "Prop" & i, ExcelSheet.Cells(Row+i,Col).Value)
  'NEXT ' i
  Excel.Workbooks(WorkBook).Close
  'Set ExcelSheet = Nothing ' Release the object variable memory
  Set Excel = Nothing      ' Release the object variable memory
end sub
0 Kudos
Message 1 of 7
(5,239 Views)
Hello Wayne!
 
You have to know that VBS is not VB! Especially arrays are different. VBS only supports to create arrays of variant. The simple solution for you problem is to declare TempArray as a simple variable 
  Dim a,b,c,d,f,grpindex,Frs,Channels,TempArray,grpname,exRange
and just make the assign without any ReDim. 
        TempArray = .Range(NamesRange).Value
        for d = 1 to Channels
          ChanNames(d-1) = TempArray(1,d)
        Next 'd
The indexes are now 1-based.
 
After this change I ran in some other errors like undefined variable 'f'.
 
BTW: I was a little bit confused that you mixed up the DIAdem Excel commands with the OLE interface.
 
Matthias


Message Edited by Twigeater on 02-25-2008 08:44 PM
Matthias Alleweldt
Project Engineer / Projektingenieur
Twigeater?  
0 Kudos
Message 2 of 7
(5,234 Views)
First.  Thank you so much for that suggestion.  The only change I made from your response is to make ChanNames(d-1) to ChanNames(d) to make everything further down in the code work as is. 
 
In regards to your confusion about mixing the Diadem excel and the OLE access to Excel, my best explanation is that the ExcelCountSheets function is just a bit easier and cleaner to use than the .workbooks.worksheets.names needed for the OLE side.  I guess it is personal preference to use the Diadem function since it just seems pretty cool.  I don't know if that really answered your question or not.
 
Thanks again for the quick reply and I am sure to run into many more question as this is the beginning of my first Diadem application.
 
Wayne Yount
0 Kudos
Message 3 of 7
(5,229 Views)
Hello Wanye!
 
Feel free to ask if you you run in any ohter serious problemSmiley Wink
 
One last hint for today: Try you code - especially the DIAdem Excel commands  - while the XLS is already opened! IMHO some commands work not as expected!
 
Good night
 
Matthias
Matthias Alleweldt
Project Engineer / Projektingenieur
Twigeater?  
0 Kudos
Message 4 of 7
(5,226 Views)

You are correct about there being problems when Excel is already open when using the Diadem functions.  I will have to work that out as I move forward in the program.  Right now I am just trying to see if I can get Diadem to do what I need. 

If you looked at the attached spreadsheet you may pick up on the problem I just figured out this morning.  The channel names I am using come from another program that is further upstream and they cannot be changed due to other legacy software we have in place.  The problem lies with the channel names using "illegal" characters that Diadem will automatically substitute a replacement (such as / replaced with \).  This caused me great headaches until I finally realized what was happening.  I then switched from using the names taken from the spreadsheet to using the channel index for referencing the destination for the incoming data. 

One of many lessons I will certainly learn doing this program.

Thanks for the help.

Wayne

0 Kudos
Message 5 of 7
(5,202 Views)

Hi Wayne,

I also checked out your code and made some changes.  I agree with Twigeater that you should stick with all OLE commands and abandon the Excel Import Wizard functions entirely.  I also recommend you use the ArrayToChannels() command to transfer the VBS data array to channels in the DIAdem Data Portal.  It looks to me like your script left out the named data range, so I added in a dummy name (I couldn't guess the name you used) and requested the data values as a 2D array, just like you did for the names.  You'll need to tweek the "DataRange" text to match what's in the Excel file, and you'll need to uncomment those two lines-- the commented code runs on my computer and imports the correct number of channels into each group.

Ask as you have further questions,
Brad Turpin
DIAdem Product Support Engineer
National Instruments



'-------------------------------------------------------------------------------
'-- VBS script file
'-- Created on 02/23/2008 19:56:07
'-- Author: Wayne Yount
'-- Comment: Trial to import excel based results
'-------------------------------------------------------------------------------
Option Explicit  'Forces the explicit declaration of all the variables in a script.

Call DataDelAll   'clear all previous data
Dim FilePath
FilePath = AutoActPath & "fw586 results.xls"
call LoadChannels(FilePath)
 

sub LoadChannels(FilePath)
  Dim i, z, iMax, ErrNum, Excel, Sheet, WorkBook, SheetName
  Dim TempArray, NamesRange, ChanNames, DataRange
  WorkBook = NameSplit(FilePath, "N") & ".XLS"
  On Error Resume Next
  Set Excel = CreateObject("Excel.Application") ' Start Excel via OLE
  ErrNum = Err.Number
  On Error Goto 0
  IF ErrNum <> 0 THEN MsgBox ErrNum : Exit Sub
  Excel.Visible = FALSE ' Don't hide Excel during debug so you can close it manually
  'Excel.ScreenUpdating = FALSE ' Disable screen refresh
  call Excel.Workbooks.Open(FilePath) ' Open Excel File
  for Each Sheet In Excel.Workbooks(WorkBook).Sheets
    SheetName = Trim(Sheet.Name)
    z = InStr(SheetName, "Sheet")
    If Len(SheetName) = 6 and z = 0 then
      Call GroupCreate(SheetName)
      Call GroupDefaultSet(GroupCount)
      NamesRange = SheetName & "!BodyRelativeChannelNames"
      TempArray = Sheet.Range(NamesRange).Value
      iMax = UBound(TempArray, 2)
      ReDim ChanNames(iMax-1)
      for i = 1 TO iMax
        ChanNames(i-1) = "/" & TempArray(1, i)
      next
'      DataRange = SheetName & "!BodyRelativeChannelValues"
'      TempArray = Sheet.Range(DataRange).Value
      Call ArrayToChannels(TempArray, ChanNames, true, true)
    end if
  next ' Sheet
  Excel.Workbooks(WorkBook).Close
  Set Sheet = Nothing ' Release the object variable memory
  Set Excel = Nothing ' Release the object variable memory
end sub

0 Kudos
Message 6 of 7
(5,186 Views)
Brad,
 
I had already worked through the code to get all of my data to load, but I was doing this via the ChnAlloc then getting the channel index and using ChDX inside nexted loops.  This worked but took about 4 minutes for the full test set to load.
 
I implemented the ArrayToChannels method and not only did it work flawlessly it also reduced the load time to about 20 seconds or less.  I also added some additional code at the beginning to work if excel is already open and if the file I want is already open.  I will include it below for others to use.
 
Thanks again for everyone's help.  I am now on to creating calculated channels from the data that was loaded and then to doing graphs and polynomial fits of the data.  I am sure I will come across questions as I forge into this area for the first time.
 
Wayne
 
'-------------------------------------------------------------------------------
'-- VBS script file
'-- Created on 02/23/2008 19:56:07
'-- Author: Wayne Yount
'-- Comment: Trial to import excel based results
'-------------------------------------------------------------------------------
Option Explicit  'Forces the explicit declaration of all the variables in a script.

Call DataDelAll   'clear all previous data
Dim FilePath
FilePath = "C:\Documents and Settings\Wayne Yount\Desktop\_path\fw586 results.xls"
call LoadChannels (FilePath)
sub LoadChannels (FilePath)
  Dim d,m,n,z,Channels,TempArray
  Dim Excel, WorkBook, TempData,ExOpen,IsWorkbookOpen
  Dim SheetName,Sheet,NumSheets,ChanNames,ChNamesRange,DataRange
  ExOpen = True
  WorkBook = NameSplit(FilePath, "N") & ".XLS"
  On Error Resume Next
  Set Excel = GetObject(,"Excel.Application") ' Get Excel via OLE if it is open already
  If Err.Number <> 0 Then
    Err.Clear
    Set Excel = CreateObject("Excel.Application") ' Start Excel via OLE
    If Err.Number <> 0 Then
      Exit Sub
    End If
    ExOpen = False
  End If
  Excel.Visible = true ' Don't hide Excel during debug so you can close it manually
  'Excel.ScreenUpdating = FALSE ' Disable screen refresh
  IsWorkbookOpen = Excel.Workbooks(WorkBook) Is Nothing = False
  If ExOpen Then
    If Not IsWorkbookOpen then
      call Excel.Workbooks.Open(FilePath) ' Open Excel File if not open already
    End If
  else
    call Excel.Workbooks.Open(FilePath) ' Open Excel File since excel was not already open
  End If
  On Error Goto 0
  for Each Sheet In Excel.Workbooks(WorkBook).Sheets
    SheetName = Trim(Sheet.Name)
    z = InStr(SheetName, "Sheet")
    If Len(SheetName) = 6 and z = 0 then
      Call GroupCreate(SheetName)
      Call GroupDefaultSet(GroupCount) 'sets newly created group as the default
      m = 1 'get body relative data first
      do
        if m = 1 then
          ChNamesRange = SheetName & "!BodyRelativeChannelNames"
          DataRange = SheetName & "!BodyRelative"
          m = m + 1
        else
          n = m - 1
          On Error Resume Next
          ChNamesRange = SheetName & "!Interpolation" & n & "ChannelNames"
          DataRange = SheetName & "!Interpolation" & n
          p = Sheet.Names(DataRange).Name 'check to see if name exists
          If Err.Number <> 0 then
            On Error Goto 0     
            exit do              'name doesn't exist so go to next workbook
          else
            m = m+1          'name is good increment to next number for next pass
          end if
        end if
        TempArray = Sheet.Range(ChNamesRange).Value
        Channels = UBound(TempArray, 2)
        ReDim ChanNames(Channels-1)
        for d = 1 to Channels
          ChanNames(d-1) = "/" & TempArray(1,d)
        Next 'd
        TempData = Sheet.Range(DataRange).Value
        Call ArrayToChannels(TempData,ChanNames,true,true)
      Loop
    end if
  next 'sheet
  Call ChnCharacterAll()
  Excel.Workbooks(WorkBook).Close
  Set Sheet = Nothing      ' Release the object variable memory
  Set Excel = Nothing      ' Release the object variable memory
end sub
0 Kudos
Message 7 of 7
(5,172 Views)