LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Trouble passing numeric and string variables to SetTableCellRangeAttribute function

Hi,
Having read various posts on ways of speeding up data entry in LabWindows/CVI tables, I wish to replace instances of SetTableCellRangeVals with the SetTableCellRangeAttribute function in my code, but there seems to be a difference in the way these functions read the variables, e.g.:

// This works... (ListGetDataPtr(CellNumbers) is treated as an array.)
SetTableCellRangeVals (panel, PANEL_TABLE, MakeRect(FirstRow, 1, Rows, Cols), ListGetDataPtr(CellNumbers), VAL_ROW_MAJOR);

// However, this alternative gives a fatal run-time error because the table cells expect floating numbers:  Invalid argument type: found 'pointer to void', expected 'double'.
SetTableCellRangeAttribute (panel, PANEL_TABLE, MakeRect(FirstRow, 1, Rows, Cols), ATTR_CTRL_VAL, ListGetDataPtr(CellNumbers));

I have a similar problem with a dynamically allocated array of strings set up as follows:

char **Buf = 0;
int items = ListNumItems(CellStrings), index, mem_error;
                                  
if ((Buf = malloc(items * sizeof(*Buf))) == NULL)
    mem_error = TRUE;
else for (index = 0; index < items; index++)
             if ((Buf[index] = malloc(256 * sizeof(Buf))) == NULL)
                  {
                   mem_error = TRUE;
                   break;
                  }
            else strcpy(Buf[index], ListGetPtrToItem (CellStrings, index));

// (code to handle possible memory error here)   
                 
// This works...
SetTableCellRangeVals (panel, PANEL_TABLE, MakeRect(FirstRow, Cols, Rows, 1), Buf, VAL_COLUMN_MAJOR);
    
// This alternative only gives gibberish...
SetTableCellRangeAttribute (panel, PANEL_TABLE, MakeRect(FirstRow, Cols, Rows, 1), ATTR_CTRL_VAL, Buf);

// This version only duplicates the contents of the first array element (which is the actual pointer?)...
SetTableCellRangeAttribute (panel, PANEL_TABLE, MakeRect(FirstRow, Cols, Rows, 1), ATTR_CTRL_VAL, *Buf);

Do I need to cast the data in some way? Any help appreciated please.

John.

0 Kudos
Message 1 of 8
(5,062 Views)

I think you are out of luck, here. Although it is generally true that the use of SetCtrlAttribute(...ATTR_CTRL_VAL...) approach is broadly equivalent to SetCtrlVal() and can often be used to improve drawing performance by deferring the screen update until several controls are ready to be drawn, in this partiular case the functions SetTableCellRangeAttribute(...ATTR_CTRL_VAL...) and SetTableCellRangeVal() are not similar enough. As you have already found, the first of these sets all cells in the range to the same value, while the second function allows the range of cells to take on different values as specified in the array parameter to the function.

I suspect that the performance of this second function would not be as degraded as you might expect - it should be able to take full advantage of having a whole bunch of values specified to it in one go and just doing the screen drawing once.

JR

0 Kudos
Message 2 of 8
(5,042 Views)
Thanks for the feedback JR. I need to fill tables of up to 7 columns wide but with over 65,000 rows. My data files are CSV ASCII with mixed string and float data types containing grouped test result batches of around 200 rows. Data are therefore non-contiguous, so multiple calls to SetTableCellRangeVal()are required for every column group of 200 rows. It takes around 5 minutes to fill the table. It takes MS Excel just a few seconds by comparison, but I must use my CVI app and I cannot convert the file contents to all strings as graphical manipulation and calculations must be performed on the data when subsequently accessed from the table. If I omit the code to fill the table, it just takes a few seconds to read these large files, so the problem doesn't seem to lie there. The table control is hidden before updating and ProcessDrawEvents() is not called. I tried explicitly making another control active to no avail. A group of new table rows are inserted on the fly as the beginning and end of a new data batch is identified in the CSV file. I changed this by inserting a fixed number of table rows at the start before loading the data to avoid time delays from repeated function calls, but it made little difference. I noticed that for a 6,000-line test file, it took much longer to fill a table with 70,000 rows than one with 7,000 rows. I wonder why this is, when I think I have taken every precaution to avoid a table re-draw. Might it be that SetTableCellRangeVal()re-draws the table after each call (as opposed to each cell entry during the call)?
0 Kudos
Message 3 of 8
(5,024 Views)
Hello John.

Do you really need to hold all of your data in the table?

Perhaps you could store just the "header" information for each batch of results in the table, and hold the numeric data in one or more arrays of int / double, arranged for easy plotting on a graph or stripchart. Each row of the table could include an offset value you can use to access the corresponding data.

Just a thought.

Regards,
Colin.
0 Kudos
Message 4 of 8
(5,013 Views)
Hello Colin,
Unfortunately, the user must be able to browse the raw data from within the app. All batch results are labeled and so can be easily found by using the built-in search facility from the pop-up menu presented when right-clicking on the table. It seems strange that it takes so long to fill the table when there should be no re-draws. I suspect however, that the table is indeed being somehow re-drawn even when it is hidden, because larger tables take much longer to update than smaller ones in cases where only the same number of cells are being filled in each.
John.
0 Kudos
Message 5 of 8
(5,000 Views)
Hello John.

Take a look at this thread. Here Luis suggests that the use of repeated calls to SetTableCellAttribute (... , ATTR_CTRL_VAL,...), while the table is NOT*** the active control, will help performance, because the redrawing operations are deferred.

Good luck.
Colin.

*** Be sure to read all of Luis' posts.
0 Kudos
Message 6 of 8
(4,991 Views)
Hello Colin,

I have tried both hiding the table and making another control active, with no noticible change in speed. Perhaps I have overlooked something in my code. I will check again. Thanks for the help.

John.
0 Kudos
Message 7 of 8
(4,913 Views)
John,

If you can post a small, sample project that shows this behavior, I'll be happy to investigate it and see if there are any improvements that can be made. I can at least find out if there is unnecessary drawing that is taking place (although from what you've written so far, I don't think there is). It's possible that it just can't be made any faster than it already is. But in any case, I'd be happy to look into it.

Luis
NI
0 Kudos
Message 8 of 8
(4,900 Views)