Issue with if else elseif and while

My appdesigner code begins by writing the first set of answers to file. The first set of answers start on tab press (i.e., on tab press = instruction and question loads; client selects answers, client presses submit). The first set of answers are written when the SubmitAnswers button is pressed. The 'if loop' then presents the remaining questions and writes these to file. I'm having an issue with the "if statement". When I use <=, the app presents all the remaining questions but I get a "row index exceeds table dimensions' error which makes sense because the row index would be 9. However, the app should not process this and should instead go to the elseif statement but the app won't go to the "elseif statement" and process the questions from the next sheet. I've also tried < but then the app only does up to question 7 and misses the last question. I tried "WriteMode Append" but this command appends all answers and I only want the client's answers for one set of questionnaires in the app. If anyone can be of assistance, I would appreciate it. Someone told me that if I read the table in and write it out again, the rows would append. This also is not working in my code below.
% Button pushed function: SubmitAnswersButton
function SubmitAnswersButtonPushed(app, event)
readtable("Answers.xlsx","ReadVariableNames",false,"Sheet","NEQA");
writetable(app.Answers, 'Answers.xlsx', 'Sheet', "NEQA"); %, 'WriteMode', 'Append'); % write the values to the table Answers.xlsx as a backup - should be all questions from all sheets to one page
writetable(app.Answers, app.filenm, 'Sheet', "NEQA"); %, 'WriteMode', 'Append'); % write the answers to the client's excel file;
% collects answers when "Submit" button pushed and writes question and answers to file
if app.NEQCurrentCount < app.NumberOfNEQQuestions
app.NEQCurrentCount = app.NEQCurrentCount + 1; % NEQ question counter
app.NEQsheet_counter = 1; % first sheet in Questionnaires_NEQ.xlsx
app.Answers = table;
%load next question
app.NEQColumns = 3:2:width(app.NEQQuestions);
app.NEQInstructions = readtable('Questionnaires_NEQ.xlsx',"ReadVariableNames",false,"TextType","string","Range","A1"); %height will not work unless readtable comes first; % Succeeds because the sheet counter is a scalar
app.NumberOfNEQInstructions = height(app.NEQInstructions); % total number of instructions; just in case future projects require more rows for instructions;
app.NEQInstructionsTextArea.Value = app.NEQInstructions{1,1}; % writes the instruction in the front panel box from the row count and column 1
app.NEQQuestions = readtable('Questionnaires_NEQ.xlsx',"ReadVariableNames",false,"TextType","string","Sheet", app.NEQsheet_counter); % Succeeds because the sheet counter is a scalar
app.NEQQuestionsTextArea.Value = app.NEQQuestions{app.NEQCurrentCount,2}; % ROW INDEX ERROR OCCURS HERE
selectedButton1.Text = app.ButtonGroup_NEQF.SelectedObject.Text;
selectedButton2.Text = app.ButtonGroup_NEQT.SelectedObject.Text;
selectedButton3.Text = app.ButtonGroup_NEQE.SelectedObject.Text;
newRow = {app.NEQQuestionsTextArea.Value{1}, [selectedButton1.Text], [selectedButton2.Text], [selectedButton3.Text]};
app.Answers = [app.Answers; newRow]; % inserts new row in answer 'file'
readtable("Answers.xlsx","ReadVariableNames",false,"Sheet","NEQA")
writetable(app.Answers, 'Answers.xlsx', 'Sheet', "NEQA");%, 'WriteMode', 'Append'); % write the values to the table Answers.xlsx as a backup - should be all questions from all sheets to one page
writetable(app.Answers, app.filenm, 'Sheet', "NEQA"); % 'WriteMode', 'Append'); % write the answers to the client's excel file; writes the question in the front panel box from the row count and column 2
app.DummyButton1.Value = 1;
app.DummyButton2.Value = 1;
app.DummyButton3.Value = 1;
% Presents Questions for Sheet 2
elseif (app.NEQCurrentCount > app.NumberOfNEQQuestions) % if the question counter is less than the number of questions
app.NEQsheet_counter = app.NEQsheet_counter + 1;
more code
end
end

 采纳的回答

frakenberry - the problem might be the first line in the body of the if statement
if app.NEQCurrentCount < app.NumberOfNEQQuestions
app.NEQCurrentCount = app.NEQCurrentCount + 1; % NEQ question counter
where app.NEQCurrentCount is immediately incremented by one. Can this be the last statement in this body?
if app.NEQCurrentCount <= app.NumberOfNEQQuestions
app.NEQsheet_counter = 1; % first sheet in Questionnaires_NEQ.xlsx
app.Answers = table;
%etc.
app.NEQCurrentCount = app.NEQCurrentCount + 1; % NEQ question counter
elseif (app.NEQCurrentCount > app.NumberOfNEQQuestions)
app.NEQsheet_counter = app.NEQsheet_counter + 1;
% etc.
end
I guess it all depends upon what NEQCurrentCount has been initialized to - zero or one? And do we ever need to reset this counter (like when we change sheets)?
I'm also wondering about
app.NEQsheet_counter = 1; % first sheet in Questionnaires_NEQ.xlsx
. Doesn't this automatic reset to one conflict with the code in the body of the elseif?
app.NEQsheet_counter = app.NEQsheet_counter + 1;
Finally, you mention The 'if loop' then presents the remaining questions and writes these to file. This isn't a "loop". Do you want to be using a loop (with for or while)?

8 个评论

NEQCurrentCount was initialized to 1. The NumberOfNEQQuestions is 8 (number of questions in the first sheet of the excel file). I also tried NEQCurrentCount < 9 and NEQCurrentCount <= 8.
app.NEQsheet_counter counts sheets in the excel file and presents the first sheet in the excel file. There are two sheets in this file. I don't need this line:
app.NEQsheet_counter = 1;
The same thing happens with and without that line of code so I've commented it out for now. All questions are presented but the last question is not written to file and I get the row index error (where I show it above in the code). That is, the client file only shows and writes the answer to the 7th question. I'm guessing the previous question and answers are overwritten because I'm not using "WriteMode Append".
I can't even get to the elseif because of the index error.
Sorry, I meant the if statement. I've tried both for and while loops as well. The while loop presents only the first and last question. Not sure why that happens. I tried a for loop as well but I can't remember what happened with that (another error).
I probably don't know exactly what the elseif is supposed to do. I thought the elseif would run if the if statement was false. Wouldn't the if statement be false when the questions get to 9? In which case, would the elseif statement start? I'm not getting that far though. The code correctly presents each question and I can respond to each one. The answers write to file if I use WriteMode Append but this keeps adding to the client file. If I don't use WriteMode Append, only 1 answer is written to file.
Thanks for looking at this.
But you see how
if app.NEQCurrentCount <= app.NumberOfNEQQuestions
app.NEQCurrentCount = app.NEQCurrentCount + 1; % NEQ question counter
might be a problem for when app.NEQCurrentCount == app.NumberOfNEQQuestions? Because we immediately increment this value by one and so it is now 9 within the body of the if statement and so the
app.NEQQuestionsTextArea.Value = app.NEQQuestions{app.NEQCurrentCount,2};
will fail with an index error (presumably this is the line that throws the error). That's why I suggest incrementing this counter as the last line of the if statement...so that next time we enter the SubmitAnswersButtonPushed callback, the counter will be greater than 8 and we will enter the elseif workflow. In fact the elseif can be removed and just replaced with an else as
if app.NEQCurrentCount <= app.NumberOfNEQQuestions
app.NEQsheet_counter = 1; % first sheet in Questionnaires_NEQ.xlsx
app.Answers = table;
%etc.
%.
%.
app.NEQCurrentCount = app.NEQCurrentCount + 1; % <-- LAST LINE
else
app.NEQsheet_counter = app.NEQsheet_counter + 1;
app.NEQCurrentCount = 1; % <--- maybe??
% etc.
end
Sorry for the delay in response. Police issued another warning in Nova Scotia about gunfire. All safe now, I guess.
That seems to have worked. I moved the NEQCurrentCount as suggested. I have one small problem. After the second sheet loads (i.e., when else starts), the instructions for the second sheet only stay on for the first question and then revert back to the instructions for sheet 1. This is the code after else:
else
app.NEQsheet_counter = app.NEQsheet_counter + 1;
app.NEQCurrentCount <= app.NumberOfNEQQuestions; % if the question counter is less than the number of questions
app.Answers = table;
app.NEQCurrentCount = 1;
app.NEQColumns = 3:2:width(app.NEQQuestions);
app.NEQInstructions = readtable('Questionnaires_NEQ.xlsx',"ReadVariableNames",false,"TextType","string","Range","A1","Sheet",app.NEQsheet_counter); %height will not work unless readtable comes first; % Succeeds because the sheet counter is a scalar
app.NumberOfNEQInstructions = height(app.NEQInstructions); % total number of instructions; just in case future projects require more rows for instructions;
app.NEQInstructionsTextArea.Value = app.NEQInstructions{1,1}; % writes the instruction in the front panel box from the row count and column 1
app.NEQQuestions = readtable('Questionnaires_NEQ.xlsx',"ReadVariableNames",false,"TextType","string","Sheet", app.NEQsheet_counter); % Succeeds because the sheet counter is a scalar
app.NEQQuestionsTextArea.Value = app.NEQQuestions{app.NEQCurrentCount,2}; %
selectedButton1.Text = app.ButtonGroup_NEQF.SelectedObject.Text;
selectedButton2.Text = app.ButtonGroup_NEQT.SelectedObject.Text;
selectedButton3.Text = app.ButtonGroup_NEQE.SelectedObject.Text;
newRow = {app.NEQQuestionsTextArea.Value{1}, [selectedButton1.Text], [selectedButton2.Text], [selectedButton3.Text]};
app.Answers = [app.Answers; newRow]; % inserts new row in answer 'file'
writetable(app.Answers, 'Answers.xlsx', 'Sheet', app.NEQsheet_counter, 'WriteMode', 'Append'); % write the values to the table Answers.xlsx as a backup - should be all questions from all sheets to one page
writetable(app.Answers, app.filenm, 'Sheet', app.NEQsheet_counter, 'WriteMode', 'Append'); % write the answers to the client's excel file; writes the question in the front panel box from the row count and column 2
app.DummyButton1.Value = 1;
app.DummyButton2.Value = 1;
app.DummyButton3.Value = 1;
end
Hope all is well in NS - it's been an awful week there.
Your second line in the else
app.NEQCurrentCount <= app.NumberOfNEQQuestions; % if the question counter is less than the number of questions
doesn't seem to serve any purpose. Should it do something?
As for resetting to the first page, you did remove the line
app.NEQsheet_counter = 1; % first sheet in Questionnaires_NEQ.xlsx
from the if body? I think that you mentioned you commented it out, but it does need to be removed.
I suspect there is also some duplication in the if and else bodies...this may cause problems the next time the callback is called. I would remove all the duplicated code to outside of the two blocks.
Hi Geoff,
Yes, everything is safe now in NS. Lots of police one the scenes. I think after the first shooting, they wanted to make sure everyone was adequately warned if someone was shooting a gun.
I removed the line of code for the counter as suggested and the
app.NEQCurrentCount <= app.NumberOfNEQQuestions; % if the question counter is less than the number of questions
but now I'm getting that row index error in the else statement at
app.NEQQuestionsTextArea.Value = app.NEQQuestions{app.NEQCurrentCount,2}; %
Should I change the sheet_counter in the else statement to:
app.NEQsheet_counter = 2;
so that the information only comes from sheet 2? Would that work?
You have been so helpful. You have great eyes for picking out these issues! Thanks so much for your help.
Setting it to two should work... but we were already incrementing by one so that should have been the same (?). could use the debugger to figure out what is going on
I was just in the middle of the debugging when you answered back. It has to do with the CurrentCount. The code thinks it's 9 and it should go back to 1 for Sheet 2. I think if I add
app.NEQCurrentCount = 1;
that should reset the second sheet to question 1. Will that make the if statement rerun from the beginning? I could set the NEQsheet_counter = 1; in the if statement so that it restricts to the first sheet and do the same for the second sheet. Would that work?
Do you know of a way to use a for loop instead?
if you want to use a for loop, then you could do something like
for k = 1:app.NumberOfNEQQuestions
app.NEQCurrentCount = k; % NEQ question counter
% some code
end
once that is complete then you would move on to the next sheet (and so you would need to indicate somehow that the sheet number has changed. As for the code in the for loop it would be similar to what you have above but you probably wouldn't have to continually read from the Excel file - you would just do that once, and then add each question, and then update the file.

请先登录,再进行评论。

更多回答(0 个)

类别

帮助中心File Exchange 中查找有关 Loops and Conditional Statements 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by