02-06-2015 07:13 AM
Actually, what you posted in your other thread is the source code for your DataPlugin. I'm asking for data files.
02-07-2015 12:21 PM
Hi All,
I got the data set, and here's the source code of the DataPlugin that puts those 3 DateTime channels together. It uses the Channel.Formatter object (for the milliseconds channel) which released with DIAdem 2012, so this won't work in older DIAdem versions.
OPTION EXPLICIT
Sub ReadStore(File)
Dim j, jMax, Block, Group, TimeChannel, Channel, ChanNames
File.Formatter.Delimiters = ","
File.Formatter.LineFeeds = vbCRLF
File.Formatter.TimeFormat = "YYYY-MM-DD hh:mm:ss"
Set Group = Root.ChannelGroups.Add(File.Info.FileName)
Call GetHdrInfo(File, ChanNames)
jMax = UBound(ChanNames)
Set TimeChannel = Group.Channels.AddProcessedChannel("DateTime", eTime, eAddProcessor)
Set Block = File.GetStringBlock()
FOR j = 1 TO jMax
Select Case j
Case 1, 2, 3
Set Channel = Block.Channels.Add(ChanNames(j), eTime)
IF j = 3 THEN Channel.Formatter.TimeFormat = "fff"
Call TimeChannel.Channels.Add(Channel)
Case ELSE
Set Channel = Block.Channels.Add(ChanNames(j), eR64)
Call Group.Channels.AddDirectAccessChannel(Channel)
End Select ' j
NEXT ' j
End Sub
Sub GetHdrInfo(File, ChanNames)
Dim j, jMax, Delim
Delim = File.Formatter.Delimiters
ChanNames = Split(Delim & File.GetNextLine, Delim)
jMax = UBound(ChanNames)
IF jMax < 3 THEN Call RaiseError()
FOR j = 1 TO jMax
ChanNames(j) = Trim(Replace(ChanNames(j), """", ""))
NEXT ' j
IF LCase(Trim(ChanNames(1))) <> "date" THEN Call RaiseError()
IF LCase(Trim(ChanNames(2))) <> "time" THEN Call RaiseError()
IF LCase(Trim(ChanNames(3))) <> "millisecond" THEN Call RaiseError()
End Sub ' GetHdrInfo()
Brad Turpin
DIAdem Product Support Engineer
National Instruments
08-25-2015 03:02 PM - edited 08-25-2015 03:03 PM
I'm trying to replicate this to a Excel Workbook Dataplugin. Same data, workbook instead of CSV ascii.
Anyways, I've got everything except merging the milliseconds again. I tried using the
Channel.Formatter.TimeFormat = "fff"
but it doesn't like that: "Object doesn't support this property or method: "TimeFormat".
I took a wizard workbook dataplugin and merged in the case statements from your code above, Brad.
The whole thing with the problm area is noted below.
Why wouldn't this work with workbook, but it does ascii? The Channel object should be identical, right?
What I cannot do with workbook is provide Formatter.TimeFormat = "YYYY-MM-DD hh:mm:ss" at the top. workbook.formatter isn't available.
Sub ReadStore(Workbook)
Dim oSheet, oGrp, oChn, oBlock, sGrpName, sChnName, lColumns, lIndex, sType, sTypeGuess, clOriginCol, clOriginRow, TimeChannel
If Workbook.Sheets.Count<1 Then Call RaiseError()
' Workbook.Formatter.TimeFormat = "YYYY-MM-DD hh:mm:ss"
Set oSheet = Workbook.Sheets(1)
'Identify file by cell address and value.
'This can be adapted to your format.
If "Date"<>CStr(oSheet.GetCellValue(1, 1)) Then Call RaiseError()
'Loop for worksheets
For Each oSheet In Workbook.Sheets
'Get minimum column and row index.
'This can be adapted to your format.
clOriginCol = oSheet.MinPosition.Column
clOriginRow = oSheet.MinPosition.Row
'Get channel group name and add a group.
'This can be adapted to your format.
sGrpName = oSheet.Name
Set oGrp = Root.ChannelGroups.Add(sGrpName)
'Add channel group properties.
On Error Resume Next
Call oGrp.Properties.Add(CStr("Name"), oSheet.Name)
On Error GoTo 0
If Not SkipSheet(oSheet) Then
'Get cell block.
'Row/Column index can be adapted to your format.
Set oBlock = oSheet.GetCellBlock(2+clOriginRow-1, clOriginCol)
'Calculate the number of columns.
lColumns = oSheet.MaxPosition.Column-clOriginCol+1
Dim eaChnDataType : ReDim eaChnDataType(lColumns) ' channel datatype
Dim asDlgChnName : ReDim asDlgChnName(lColumns) ' channel name
'Loop for columns.
For lIndex = 1 To lColumns
'Set default channel datatype, channel name can be adapted to your format.
Select Case lIndex
Case 1, 2, 3
eaChnDataType(lIndex) = eI32 'eI32 is for auto-detection only, use it by default. If you want fixed datatype, you can specify it later.
asDlgChnName(lIndex) = oSheet.GetCellValue(1+clOriginRow-1, clOriginCol-1+lIndex)
Case ELSE
eaChnDataType(lIndex) = eI32 'eI32 is for auto-detection only, use it by default. If you want fixed datatype, you can specify it later.
asDlgChnName(lIndex) = oSheet.GetCellValue(1+clOriginRow-1, clOriginCol-1+lIndex)
End Select 'lIndex
Next
'eI32 is for auto-detection only, for fixed datatype, please directly specify eR64/eTime/eString here
On Error Resume Next
'Create and add channels.
On Error GoTo 0
Set TimeChannel = oGrp.Channels.AddProcessedChannel("DateTime", eTime, eAddProcessor)
For lIndex = 1 To lColumns
sChnName = asDlgChnName(lIndex)
sType = eaChnDataType(lIndex)
'Add DirectAccessChannel to cell block.
If eaChnDataType(lIndex)=eNoType Then sChnName = "____ignored____" : sType = eString
If sType=eI32 Then 'eI32 is for auto-detection only, try getting the actual datatype
Dim lRowIndexTemp
For lRowIndexTemp = 2+clOriginRow-1 To oSheet.MaxPosition.Row
sType = oSheet.GetCellType(lRowIndexTemp, clOriginCol-1+lIndex)
If sType<>eNoType Then Exit For
Next
If sType=eNoType Then sType=eI32
End If
Select Case lIndex
Case 1, 2, 3
stype = eTime
Set oChn = oBlock.Channels.Add(sChnName, eTime)
'***** Problem line
IF lIndex = 3 THEN oChn.Formatter.TimeFormat = "fff"
'*****
Call TimeChannel.Channels.Add(oChn)
Case ELSE
If sType=eI32 Then 'eI32 is for auto-detection only, use the auto-detection of cell block
Set oChn = oBlock.Channels.Add(sChnName)
Else
Set oChn = oBlock.Channels.Add(sChnName, sType)
End If
If eaChnDataType(lIndex)<>eNoType Then
Call oGrp.Channels.AddDirectAccessChannel(oChn)
'Add channel properties.
On Error Resume Next
On Error GoTo 0
End If
End Select 'lIndex
Next 'column
End If' If Not SkipSheet(oSheet)
Next 'worksheet
End Sub 'ReadStore
'Determine whether a worksheet should be skipped.
'The function can be adapted to your format
Function SkipSheet(Sheet)
SkipSheet = True
If Sheet.MinPosition.Row>0 And Sheet.MinPosition.Column>0 Then SkipSheet = False
End Function
08-26-2015 10:31 AM
Hi sg,
Are the various columns of type numeric or datetime in Excel? Can you send over a sample Excel file?
Brad Turpin
DIAdem Product Support Engineer
National Instruments
08-26-2015 10:34 AM
Thanks for the reply.
Column 1 and 2 are Date and Time respectively.
All others including column 3 (Milliseconds) are general numeric.
Sample xls attached.
08-26-2015 02:22 PM - edited 08-26-2015 02:22 PM
Hi Scott,
There's no way in a DataPlugin DirectAccessChannel to parse the string in a numeric Excel column according to a datetime pattern. There are two ways to go here. The most efficient way, which is best for large data files, is to parse the DateTime columns down to the second with DirectAccessChannels and put them together with a PocessedChannel, then load the "Millisecond" column as a numeric channel and add that channel to the DateTime channel with a script:
Call Data.Root.Clear Call DataFileLoad(DataFilePath, "Scott_XLS") Set Group = Data.Root.ActiveChannelGroup Call ChnAdd(Group.Channels(1), Group.Channels(2), Group.Channels(1)) Call Group.Channels.Remove(2)
If you have small data sets, then the alternative would be to read the values row by row in the DataPlugin and construct each DateTime value all the way down to the millisecond level and add those directly to the DateTimeChannel.Values() collection. Let me know if you prefer this method.
Brad
08-27-2015 11:33 AM - edited 08-27-2015 11:35 AM
Thanks Brad.
Of course the script cannot explicitly call the data file, the names and folders change constantly, so to do with block I really need to do this all with a 2nd user action. ick.
I'll have to judge how big is too big (50 channels, anything between 100 and 100k rows) and how long it takes to do row by row I suppose. I tried it, with the file you provided it doesn't seem to take much longer than what I was dealing with on the .csv version.
Looks like I'll be adding a request to Idea Exchange for TimeFormatter support. This is sort of a bummer. 🙂
--Scott
08-27-2015 11:53 AM - edited 08-27-2015 11:54 AM
@Brad_Turpin wrote:
There's no way in a DataPlugin DirectAccessChannel to parse the string in a numeric Excel column according to a datetime pattern.
I should note, that Formatter.TimeFormat DOES come up in the code completion, so one would have presumed it would work. But alas.... 🙂
08-27-2015 02:58 PM
Hi Scott,
Here's the "slow" implementation that does all the datetime parsing in the DataPlugin. I hope it's fast enough for your data files...
Brad Turpin
DIAdem Product Support Engineer
National Instruments
09-01-2015 07:29 AM
That worked great. Thank you Brad. I don't think it was much slower than the csv script. A bit more front end before I see the gree process bar in the lower right do anything, but the processs bar doesn't run for very long, and the csv script was just about the opposite.