App Designer table won't populate or auto-update

Hello all!
This is my first time using the app designer. In general I make codes and am familiar with the way that I did so, and I just work in the .m file. Recently however, I've undertaken a few projects that will require other people to interact with my code, most of which have no coding experience at all, let alone with Matlab, so I've decided to make an application instead of my traditional way of doing it.
I'm essentially creating a database for building keys, and the overall code is very simple, but I'm having trouble with the display. Because the excel I'm storing the info in when the app is not open doesn't populate changes until it is re-opened, I want to have a table within the app display all of the information that is there, but I'm having trouble getting that data to display, even in its original state called in the startup function. Beyond that, I would also like it to auto update, but I believe once I figure out how to populate the table I should be able to do that relatively simply. I'm not getting any errors with my code, but the table remains completely blank.
Attachments:
Table that should be populated with data, but is blank:
My startup function code:
clc;
app.fullFileName= fullfile(app.folder,app.baseFileName);
if ~exist(app.folder,'dir')
mkdir(app.folder);
end
if ~exist(app.fullFileName,"file")
writematrix(app.infoDesc,app.fullFileName,'Range','A1:D1');
end
app.prevKeyData = readmatrix(app.fullFileName,"OutputType","string", "FileType","spreadsheet",TreatAsMissing="",ExpectedNumVariables=4);
app.prevKeyDataTab = readtable(app.fullFileName,VariableNamingRule='preserve',TreatAsMissing='');
app.infoDesctab = {"Serial Number","Door(s) Accessible","Number of Existing Keys","Room Owner(s)"};
app.prevKeyDataTab = app.prevKeyDataTab(2:size(app.prevKeyDataTab),app.spaceHolder);
app.UITable.Data = app.prevKeyDataTab;
If it's necessary for troubleshooting, I can also attach the .mlapp file I'm working with, but didn't know if that was customary to do with App Designer requests, so I've elected to leave it off the original post.
Thanks in advance for any help! As I said, this is the first time I've used this, so it could very well be a really dumb mistake, but I haven't been able to figure it out for the last hour or so.

Answers (1)

Voss
Voss on 24 Aug 2023
Edited: Voss on 24 Aug 2023
Assuming the Excel file doesn't already exist, you do this:
writematrix(app.infoDesc,app.fullFileName,'Range','A1:D1');
Range is one row, so only one row is written to file, even if app.infoDesc contains more than one row.
  • If the range you specify is smaller than the size of the input data, then the writing function writes only a subset of the input data that fits into the range.
Then, you read the file into a table variable:
app.prevKeyDataTab = readtable(app.fullFileName,VariableNamingRule='preserve',TreatAsMissing='');
and keep (some columns of) rows 2 through the end of it:
app.prevKeyDataTab = app.prevKeyDataTab(2:size(app.prevKeyDataTab),app.spaceHolder);
But the table variable app.prevKeyDataTab only had one row initially (when it was created by readtable), so now (after keeping only rows 2 through end) it will have zero rows.
Then app.UITable is populated with app.prevKeyDataTab, which is empty, so the uitable is empty.

8 Comments

You should step through the startup function with the debugger and make sure the variables are what you expect.
If you don't see anything awry (or amiss or afoul or askew), then please do upload the .mlapp file and initial Excel file if you're using one.
Voss, did as you said and got some expected and some unexpected things. Up until the line defining the table as itself from indices 2 to the size of the table, everything works fine. The point of that if statement at the beginning is to ensure the program has somewhere to write data to, but in this case I already have an excel file (with complete dummy data, however it is still there) that exists so I don't think your first point is the issue. However, something strange happens in the following code:
app.prevKeyDataTab = app.prevKeyDataTab(2:size(app.prevKeyDataTab),app.spaceHolder);
That yields a 2x0 empty table. I honestly don't even know what I want this step to do, I used the built in example table from Matlab's documentation and they had a similar line, so I added it, but I'm unsure of why it's necessary. Here's the output I get from running the code in a piecewise, line-by-line fashion:
% First pause point
99 app.prevKeyData = readmatrix(app.fullFileName,"OutputType","string", "FileType","spreadsheet",TreatAsMissing="",ExpectedNumVariables=4);
app.prevKeyData
ans =
[]
% Next line of code
app.prevKeyData
ans =
4x4 string array
Columns 1 through 3
"Serial Number" "Door(s) Accessible" "Number of Existi..."
"1" "1" "1"
"2" "2" "2"
"3" "3" "3"
Column 4
"Room Owner(s)"
"1"
"2"
"3"
app.prevKeyDataTab
ans =
3x4 table
Serial Number Door(s) Accessible Number of Existing Keys Room Owner(s)
_____________ __________________ _______________________ _____________
{'1'} {'1'} {'1'} {'1'}
{'2'} {'2'} {'2'} {'2'}
{'3'} {'3'} {'3'} {'3'}
% Matrix and table both print as expected
app.infoDescTab
Did you mean:
Unrecognized method, property, or field 'infoDescTab' for class
'keyTracker'.
% Small Typo here ^^ but left it in for continuity, can be ignored
app.infoDesctab
ans =
1x4 cell array
Columns 1 through 2
{["Serial Number"]} {["Door(s) Acce..."]}
Columns 3 through 4
{["Number of Ex..."]} {["Room Owner(s)"]}
% Table Title Names are fine, but next line yields an empty table?
app.prevKeyDataTab
ans =
2x0 empty table
app.UITable.Data
ans =
2x0 empty table
For further reference on what I was trying to replicate, here is the example startup function from Mathworks. I took out the aspects meant for sorting, as it wasn't really a list that needs to be in any particular order:
methods (Access = private)
% Code that executes after component creation
function startupFcn(app)
% Read table array from file
t = readtable('patients.xls');
vars = {'Age','Systolic','Diastolic','SelfAssessedHealthStatus','Smoker'};
% Select a subset of the table array
t = t(1:20,vars);
%% The preceeding line is the one I was trying to replicate the function of, with some small tweaks for formatting.
% Sort the data by age
t = sortrows(t,'Age');
% Combine Systolic and Diastolic into one variable
t.BloodPressure = [t.Systolic t.Diastolic];
t.Systolic = [];
t.Diastolic = [];
% Convert SelfAssessedHealthStatus to categorical
cats = categorical(t.SelfAssessedHealthStatus,{'Poor','Fair','Good','Excellent'});
t.SelfAssessedHealthStatus = cats;
% Rearrange columns
t = t(:,[1 4 3 2]);
% Add data to the Table UI Component
app.UITable.Data = t;
% Plot the original data
x1 = app.UITable.Data.Age;
y1 = app.UITable.Data.BloodPressure(:,2);
plot(app.UIAxes,x1,y1,'o-');
% Plot the data
updateplot(app);
end
And here is my mlapp and xlsx files if they are also necessary. Note for the excel sheet, it must be in a folder called "Data Storage" contained within the same folder as the mlapp. It will auto-generate both the folder and the file if you don't manually add them.
Thanks again!
app.prevKeyDataTab = app.prevKeyDataTab(2:size(app.prevKeyDataTab),app.spaceHolder);
That code is mistaken, as size() with a single parameter returns a vector of length at least 2, and the ":" operator always uses the first value out of the vector.
The code should probably be more like
app.prevKeyDataTab = app.prevKeyDataTab(2:end,app.spaceHolder);
provided that the second subscript is correct.
Walter,
That fixed the issue, thanks! A quick question though if you have a second. What does that line really accomplish? I understand that I need it because I want to cut the title rows off, but in the example that Matlab gave, they also had a similar line that defined it to the (seemingly) arbitrary value of 20:
t = t(1:20,vars);
Could they not have just uploaded only what part of the table existed, and would that not automatically be done with something along the lines of
t = readtable('filename.xlxs');
app.UITable.Data = t;
I'm very unfamiliar with creating a User Interface so I was curious if it was anything more than an arbitrary number they used for the example to take data up until the 20th line, or if there was some reason why this definition was necessary.
Thanks again to both of you!
Titles are stored separately from data in a table, so you don't need to cut the titles off.
I don't see how the size() issue can explain what the problem was. t(2:size(t),:) is the same as t(2:size(t,1),:) is the same as t(2:end,:). And notice that the table had 2 rows after that, but zero columns (size 2-by-0). So I suspect the problem was actually that app.spaceHolder was empty before but is not now.

Sign in to comment.

Categories

Products

Release

R2023a

Asked:

on 24 Aug 2023

Commented:

on 25 Aug 2023

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!