Home Image-Pro Plus Automation with Macros

Processing on Datacollector

Hi There
I have this macro (with A LOT of help from Yuri), that generates data in the datacollector, The processed images are not visible - the same goes for the datacollector. That saves my a lot of time when running as a batch. After batch processing are have a small script that empties the datacollector into Excel for further calculations. It would nice to make the Excel VBA coding directly in ImagePro, again to save time and trouble.
I have been experimenting a little and this line in my macro:

    Public Function FD_Measure(doc1 As Object) As SimpleScript
        FD_Measure = New SimpleScript
         - bla bla bla
         - bla bla bla
         - bla bla bla
         
         Call DoSomething()

    End Function

Then made this simple sub routine:


    Private Sub DoSomething()
        Debug.Print Now()
    End Sub

It works!:-)))

But here comes the question - In this DoSomething, how can I access the data in the datacollector. 
Loop through them, put them in arrays etc etc. I have all that code from Excel VBA.

I need something like (in mumbo-jumbo language):

For i 1 to Number_Of-lines_in-Datacolletor
      myParamx(i) = Parameter1_In_Collector(i)
      myParamy(i) = Parameter2_In_Collector(i) 
Next
Does it make any sence!? - Torben

Answers

  • edited January 2017
    Hi Torben,

    The data in DataCollecter is saved as System.Data.DataSet (see https://msdn.microsoft.com/en-us/library/system.data.dataset(v=vs.110).aspx  ).

    Here is a sample macro that shows how to print one of the tables to Output window (you can use Debug.Print instead). 

        Public Sub PrintDCdata
            'get Data Collector doc (global)
            Dim dcDoc As MediaCy.Addins.DataCollector.McDataCollectorDocument=MediaCy.Addins.DataCollector.McDataCollectorAddin.ThisAddin.Document
    
            'get data collector data as DataSet
            Dim ds As System.Data.DataSet=dcDoc.Data
            'get the first table
            Dim dt As System.Data.DataTable=ds.Tables(0)
            Dim s As String=""
            ThisApplication.Output.Show
            'print column names
            Dim col As System.Data.DataColumn
            For Each col In dt.Columns
                s+=col.Caption & vbTab
            Next
             ThisApplication.Output.PrintMessage(s)'can be used instead of Debug.Print
            'print data
            For Each row As System.Data.DataRow In dt.Rows
                 s=""
                 For Each col In dt.Columns
                    s+=row(col).ToString & vbTab
                 Next
                 ThisApplication.Output.PrintMessage(s)
            Next
        End Sub
    

    The data from Output window can be sent to Excel using context menu.

    Yuri
  • That's also (a kind of magic). It gives data from the "Image" tab of the datacollectpor. The datacollector has as tab called "Measurements" how do I get the data from that?

    -Torben
  • The macro uses the first table Tables(0), if your Measurement table is second then you should change the macro to get Tables(1):

    Dim dt As System.Data.DataTable=ds.Tables(1)

    Yuri
  • Thank you - Makes sence. But something fishy is still going on. I am trying to pickup data into arrays like this, why doesn't that work? I know it´s not really elegant, but the other parts of the VBA code expects arrays like this:

        Public Sub PrintDCdata
            'get Data Collector doc (global)
            Dim dcDoc As MediaCy.Addins.DataCollector.McDataCollectorDocument=MediaCy.Addins.DataCollector.McDataCollectorAddin.ThisAddin.Document
            Dim tmp(1000,5) As Double
            Dim r As Integer
            Dim c As Integer
    
            'get data collector data as DataSet
            Dim ds As System.Data.DataSet=dcDoc.Data
            'get the first table
            Dim dt As System.Data.DataTable=ds.Tables(1)
            Dim s As String=""
            ThisApplication.Output.Show
    
            'print column names
            Dim col As System.Data.DataColumn
            For Each col In dt.Columns
                s+=col.Caption & vbTab
            Next
    
            r=0
            c=0
    
            ThisApplication.Output.PrintMessage(s)'can be used instead of Debug.Print
            'print data
            For Each row As System.Data.DataRow In dt.Rows
                 r+=1
                 s=""
                 For Each col In dt.Columns
                    c+=1
                    s+=row(col).ToString & vbTab
                    tmp(r,c) = row(col)
                 Next
                 ThisApplication.Output.PrintMessage(s)
            Next
    
            'Debug.Print r.ToString & vbTab & c.ToString
    
        End Sub
    
  • Hi Torben,

    You have to reset column index in the beginning of every row. Add c=0 to row loop.

    Yuri
  • You are absolutely right. A strange thing happens when I do the batch (because it actually works now). It enter your function twice; I have put in a debug.print now to tell me about it. Whats the explanation and how to avoid that?

        Public Function FD_Measure(doc1 As Object) As SimpleScript
            FD_Measure = New SimpleScript
            Dim image1
            Dim docList1 = New List(1), doc3, image2

      bla bla bla.....


        PrintDCdata
       
        End Function


        Public Sub PrintDCdata
            'get Data Collector doc (global)
            Dim dcDoc As MediaCy.Addins.DataCollector.McDataCollectorDocument=MediaCy.Addins.DataCollector.McDataCollectorAddin.ThisAddin.Document
            Dim tmp(1000,10) As Double
            Dim r As Integer
            Dim c As Integer
            Dim i As Integer
            Dim k As Integer

            'get data collector data as DataSet
            Dim ds As System.Data.DataSet=dcDoc.Data

            If ds.Tables.Count < 2 Then Exit Sub

            'get the first table
            Dim dt As System.Data.DataTable=ds.Tables(1)
            Dim s As String=""
            'ThisApplication.Output.Show

            'print column names
            Dim col As System.Data.DataColumn
            For Each col In dt.Columns
                s+=col.Caption & vbTab
            Next

            r=0

            'ThisApplication.Output.PrintMessage(s)'can be used instead of Debug.Print
            'print data
            For Each row As System.Data.DataRow In dt.Rows
                 r+=1
                 s=""
                 c=0
                 For Each col In dt.Columns
                    c+=1
                    s+=row(col).ToString & vbTab
                    'tmp(r,c) = row(col)
                    tmp(r,c) = Val(row(col).ToString)
                 Next
                 'ThisApplication.Output.PrintMessage(s)
            Next

            For i =   1  To r
                For k=1 To c
                    'Debug.Print tmp(i,k)
                Next
            Next
            'Debug.Print r.ToString & vbTab & c.ToString

            Debug.Print Now

        End Sub

  • The issue is that when your function has type of SimpleScript it's executed twice, when it's loaded (for variable parsing) and when it runs. All user code inside SimpleScript must be placed inside CodeCommand, like this:

            With Automate.ScriptingCommands.CodeCommand(FD_Measure)
                If .Run() Then
                    ' User Code Here
                    PrintDCdata
                End If
            End With
    

    You can search the forum  for CodeCommand to see more examples.

    Yuri
  • Ahhh makes sense - I thoug it was something like that - Thank you...again:-))
Sign In or Register to comment.