LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Populate table using DSBindCtrl

I need to load a CSV file into a table control.  I thought I could use DSBindCtrl to do this.  The code runs without any errors, but nothing shows up in the table.  I can't find much documentation or forum entires on using DSBindCtrl.  Can someone provide an example using DSBindCtrl to load a CSV file into a table?  Is there a better way to load a CSV file into a table without having to read the file one line at a time and parse it manualy?

 

TonyG

0 Kudos
Message 1 of 5
(4,565 Views)

DSBindCtrl is part of the DataSocket library, which is aimed to making exchanging data between applications and/or PCs easier. It requires an application or a PC being on the other end of the socket and supplying data for the Bind control to operate; in full evidence this is not your  situation. Here you can find a tutorial on thisa technology.

 

You can try using FileToArray command to read the .CSV into an array and SetTableCellRangeVals to populate the table instead.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 2 of 5
(4,561 Views)

That's what I was afraid of.  Since that isn't going to work, I wrote a function that parses the CSV file line-by-line, substring-by-substring, and populates a table.  Here's the code:

 

/*************************
** LoadCsvFileIntoTable **
**************************/
static void LoadCsvFileIntoTable(int PanelHandle, int TableHandle, char *CsvFileFullPath)
{
    FILE *FileHandle = fopen(CsvFileFullPath, "r");
    
    // if we found the file...
    if (FileHandle)
    {
        char Buff[1000];
        int Rows = 0, Columns = 1;
        
        SetWaitCursor (1);
        
        // empty the table
        DeleteTableColumns(PanelHandle, TableHandle, 1, -1);        
        DeleteTableRows   (PanelHandle, TableHandle, 1, -1);        

        // start with one column (and no rows)
        InsertTableColumns(PanelHandle, TableHandle, -1, 1, VAL_CELL_STRING);
        
        // for each line in the file...
        while (fgets(Buff, sizeof(Buff), FileHandle))
        {
            int i, CommaCount;
            int Column;
            
            // count the number of commas in this line
            for (i = CommaCount = 0; i < strlen(Buff); i++)
            {
                if (Buff[i] == ',') ++CommaCount;
            } /* for */
            
            // if we need to add more columns...
            if (Columns <= CommaCount)
            {
                // insert the number of columsn needed
                InsertTableColumns(PanelHandle, TableHandle, -1, CommaCount - Columns + 1, VAL_CELL_STRING);
                Columns = CommaCount + 1;
            } /* if-thne */
            
            // add a new row
            InsertTableRows   (PanelHandle, TableHandle, -1, 1, VAL_CELL_STRING);
            ++Rows;
            
            // if there were no commas...
            if (CommaCount == 0)
            {
                // copy the entire buffer to the first cell in the row
                FillTableCellRange (PanelHandle, TableHandle, MakeRect(Rows, 1, 1, 1), Buff);
            } /* if-then */
            else
            {
                // get the first string
                char *PtrToNextString = strtok(Buff, ",");
                
                // copy the first substring to the first cell
                Column = 1;
                SetTableCellVal(PanelHandle, TableHandle, MakePoint(Column, Rows), PtrToNextString);
                
                // for each subsequent substring...
                while (PtrToNextString = strtok(NULL, ","))
                {
                    // copy the substring into the current cell
                    ++Column;
                    SetTableCellVal(PanelHandle, TableHandle, MakePoint(Column, Rows), PtrToNextString);
                } /* while */
            } /* if-else */
        } /* while */
        
        SetWaitCursor (0);
    } /* if-then */
    else
    {
        MessagePopup("Error!", "Couldn't open CSV file!");
    } /* if-else */
} /* LoadCsvFileIntoTable */

This works, but it runs very slowly.  Do you have any suggestions for speeding this up?  Is there a way to suspend GUI updates while the table is being populated (soemthing similar to CanvasStartBatchDraw)?

 

TonyG

0 Kudos
Message 3 of 5
(4,544 Views)

There are a couple of hints I can give you to speed up the process.

 

First of all, adding rows and columns one by one and populating cells one by one is a very slow process: you should scan the file and count rows and columns before populating the table: after that you can add rows and columns with one InsertTableRows and one InsertTableColumns only.

 

Creating arrays of your strings and filling the table with a few SetTableCellRangeVals calls can help further to speed up things.

 

Finally, reading the entire file in memory and working from there is the last hint: I can give you: take a look at nickb contributions in this thread to have an idea Smiley Wink



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 4 of 5
(4,540 Views)

Thanks for the suggestions.  I'm now counting the commas (columns) and rows first, then adding the rows and columns to the table.  Then I rewind the file and go through each line again.  The second time through I create an array of char pointers for each substring using strok.  When the whole row has been processed, I write the entire set of substrings to the current row.  It runs quite a bit faster, but still not as fast as I'd like.  For my purposes this is OK, but someone else might need it to be faster.

 

I'm positing the code here for anyone that wants to use it.  There are two hard coded numbers that you may want to adjust for your application:

 

1) The line buffer is 1000 characters long.  If your CSV file includes longer lines, increase this size.

2) The array for subtrings on each line (i.e., the number of columns) has a max size of 100.  If your CSV file has more columns, increase this number.

 

/*************************
** LoadCsvFileIntoTable **
**************************/
static void LoadCsvFileIntoTable(int PanelHandle, int TableHandle, char *CsvFileFullPath)
{
    FILE *FileHandle = fopen(CsvFileFullPath, "r");
    
    // if we found the file...
    if (FileHandle)
    {
        char Buff[1000];
        char *RowSubstrings[100];
        int Rows = 0, Columns = 0;
        
        SetWaitCursor (1);
        
        // empty the table
        DeleteTableColumns(PanelHandle, TableHandle, 1, -1);        
        DeleteTableRows   (PanelHandle, TableHandle, 1, -1);        

        // for each line in the file...
        while (fgets(Buff, sizeof(Buff), FileHandle))
        {
            int i, CommaCount;
            
            // count the number of commas in this line
            for (i = CommaCount = 0; i < strlen(Buff); i++)
            {
                if (Buff[i] == ',') ++CommaCount;
            } /* for */
            
            // if we need to add more columns...
            if (Columns <= CommaCount) Columns = CommaCount + 1;
            ++Rows;
        } /* while */

        // make sure we have enough substring pointers
        assert(sizeof(RowSubstrings) >= Columns);
        
        // go back to the beginning
        rewind(FileHandle);
        
        // setup the rows and columns
        InsertTableColumns(PanelHandle, TableHandle, 1, Columns, VAL_CELL_STRING);
        InsertTableRows   (PanelHandle, TableHandle, 1, Rows,    VAL_CELL_STRING);
        
        Rows = 0;
        
        // for each line in the file...
        while (fgets(Buff, sizeof(Buff), FileHandle))
        {
            // get the first string
            char *PtrToNextString = strtok(Buff, ",");
            
            ++Rows;
            
            // if there were no commas...
            if (PtrToNextString == NULL)
            {
                // copy the entire buffer to the first cell in the row
                FillTableCellRange (PanelHandle, TableHandle, MakeRect(Rows, 1, 1, 1), Buff);
            } /* if-then */
            else
            {
                // copy the first substring to the first cell
                int Column = 0;
                RowSubstrings[Column] = PtrToNextString;
                
                // for each subsequent substring...
                while (PtrToNextString = strtok(NULL, ","))
                {
                    // copy the substring into the current cell
                    RowSubstrings[++Column] = PtrToNextString;
                } /* while */
                
                // load entire row with substrings
                SetTableCellRangeVals(PanelHandle, 
                                      TableHandle, 
                                      MakeRect(Rows, 1, 1, Column + 1), 
                                      RowSubstrings, 
                                      VAL_COLUMN_MAJOR);
            } /* if-else */
        } /* while */
        
        SetWaitCursor (0);
    } /* if-then */
    else
    {
        MessagePopup("Error!", "Couldn't open CSV file!");
    } /* if-else */
} /* LoadCsvFileIntoTable */

 

TonyG

0 Kudos
Message 5 of 5
(4,518 Views)