Getting around overuse of "if" statements.

3 ビュー (過去 30 日間)
Jacob Holmes
Jacob Holmes 2021 年 7 月 13 日
コメント済み: Rik 2021 年 7 月 13 日
I have a function which takes some data and adds it to an excel file. Depending on the inputs to the function, the data is put in different rows and columns of the excel file. The input is the day, week and site the data was recorded. My code is very clunky and just involves lots of "if" and elseif" statements which make the code hard to read and it takes ages to fix the code if something goes wrong. Is there a better way to write the following code?
function FileLocation(Data,Diff,DAY,SITE,WEEK)
if SITE == 'A'
if DAY == 'Mon'
filename = 'daily records.xlsx';
writematrix(Data,filename,'Sheet',WEEK,'Range','C10:C14')
filename = 'daily records.xlsx';
writematrix(Diff,filename,'Sheet',WEEK,'Range','D10:D14')
elseif DAY == 'Tue'
filename = 'daily records.xlsx';
writematrix(Data,filename,'Sheet',WEEK,'Range','E10:E14')
filename = 'daily records.xlsx';
writematrix(Diff,filename,'Sheet',WEEK,'Range','F10:F14')
elseif DAY == 'Wed'
filename = 'daily records.xlsx';
writematrix(Data,filename,'Sheet',WEEK,'Range','G10:G14')
filename = 'daily records.xlsx';
writematrix(Diff,filename,'Sheet',WEEK,'Range','H10:H14')
elseif DAY == 'Thu'
filename = 'daily records.xlsx';
writematrix(Data,filename,'Sheet',WEEK,'Range','I10:I14')
filename = 'daily records.xlsx';
writematrix(Diff,filename,'Sheet',WEEK,'Range','J10:J14')
else
filename = 'daily records.xlsx';
writematrix(Data,filename,'Sheet',WEEK,'Range','K10:K14')
filename = 'daily records.xlsx';
writematrix(Diff,filename,'Sheet',WEEK,'Range','L10:L14')
end
end

採用された回答

Rik
Rik 2021 年 7 月 13 日
編集済み: Rik 2021 年 7 月 13 日
You should use the value of DAY to set the value of a variable you can use as the range. You should also use strcmp to compare char arrays.
In this case you can use ismember:
function FileLocation(Data,Diff,DAY,SITE,WEEK)
if strcmp(SITE,'A')
filename = 'daily records.xlsx';
days={'Mon','Tue','Wed','Thu','Fri'};
LookUpTable={...
'C10:C14','D10:D14';...
'E10:E14','F10:F14';...
'G10:G14','H10:H14';...
'I10:I14','J10:J14';...
'K10:K14','L10:L14'};
L=ismember(days,DAY);
%you could check if sum(L) is 1 here if you like
Range=LookUpTable(L,:);
writematrix(Data,filename,'Sheet',WEEK,'Range',Range{1});
writematrix(Diff,filename,'Sheet',WEEK,'Range',Range{2});
end
The point is to make sure you are not repeating code. If you have code that you are calling mutliple times, you should either consider a loop or a function. A LUT can also be helpful to avoid repeating code.
  5 件のコメント
Jacob Holmes
Jacob Holmes 2021 年 7 月 13 日
I've done the following which works and seems quite neat to me:
function ExcelExport(Data,Diff,DAY,SITE,WEEK)
filename = 'testdata.xlsx'; % Name of the excel document
days={'Mon','Tue','Wed','Thu','Fri'}; % Matrix of week days to later compare
site = {'A','A','B','B','C','C'};
LookUpTable={... %Look up table for row and column destinations for data
'C10:C14','D10:D14','C16:C20','D16:D20','C22:C26','D22:D26';...
'E10:E14','F10:F14','E16:E20','F16:F20','E22:E26','F22:F26';...
'G10:G14','H10:H14','G16:G20','H16:H20','G22:G26','H22:H26';...
'I10:I14','J10:J14','I16:I20','J16:I20','I22:I26','J22:I26';...
'K10:K14','L10:L14','K16:K20','L16:L20','K22:K26','L22:L26'};
L=ismember(days,DAY); % Logical matrix. 0s everywhere apart from where matching day is gives 1
S = ismember(site,SITE);
%you could check if sum(L) is 1 here if you like
Range=LookUpTable(L,S);
writematrix(Data,filename,'Sheet',WEEK,'Range',Range{1});
writematrix(Diff,filename,'Sheet',WEEK,'Range',Range{2});
end
Rik
Rik 2021 年 7 月 13 日
That's fine as well. You need to balance the chance of making a mistake when copy-pasting the LUT with the chance of making a mistake when writing the code that will generate the LUT. Case in point: my initial answer had 'I10:I14','I10:I14' instead of 'I10:I14','J10:J14'.

サインインしてコメントする。

その他の回答 (2 件)

Srinik Ramayapally
Srinik Ramayapally 2021 年 7 月 13 日
Hey Jacob,
You can always use a switch-case instead of multiple if/else-if statements.
Here in this case, instead of the inner if/else-if statements, i suggest you to replace that code with this
switch DAY
case 'Mon'
filename = 'daily records.xlsx';
writematrix(Data,filename,'Sheet',WEEK,'Range','C10:C14')
filename = 'daily records.xlsx';
writematrix(Diff,filename,'Sheet',WEEK,'Range','D10:D14')
case 'Tue'
filename = 'daily records.xlsx';
writematrix(Data,filename,'Sheet',WEEK,'Range','E10:E14')
filename = 'daily records.xlsx';
writematrix(Diff,filename,'Sheet',WEEK,'Range','F10:F14')
case 'Wed'
filename = 'daily records.xlsx';
writematrix(Data,filename,'Sheet',WEEK,'Range','G10:G14')
filename = 'daily records.xlsx';
writematrix(Diff,filename,'Sheet',WEEK,'Range','H10:H14')
case 'Thu'
filename = 'daily records.xlsx';
writematrix(Data,filename,'Sheet',WEEK,'Range','I10:I14')
filename = 'daily records.xlsx';
writematrix(Diff,filename,'Sheet',WEEK,'Range','J10:J14')
otherwise
filename = 'daily records.xlsx';
writematrix(Data,filename,'Sheet',WEEK,'Range','K10:K14')
filename = 'daily records.xlsx';
writematrix(Diff,filename,'Sheet',WEEK,'Range','L10:L14')
end
the case element can also accept multiple values like strings, cells etc.
Please refer to the switch,case,otherwise documentation for further reference.
  1 件のコメント
Jacob Holmes
Jacob Holmes 2021 年 7 月 13 日
Thanks Srinik!

サインインしてコメントする。


Max Heiken
Max Heiken 2021 年 7 月 13 日
I agree with Srinik Ramayapally, employing switch is the most obvious change that comes to mind. To extend on that solution, you could factor out the code common to all cases.
switch DAY
case 'Mon'
range1 = 'C10:C14';
range2 = 'D10:D14';
case 'Tue'
range1 = 'E10:E14';
range2 = 'F10:F14';
case 'Wed'
range1 = 'G10:G14';
range2 = 'H10:H14';
case 'Thu'
range1 = 'I10:I14';
range2 = 'J10:J14';
otherwise
range1 = 'K10:K14';
range2 = 'L10:L14';
end
filename = 'daily records.xlsx';
writematrix(Data,filename,'Sheet',WEEK,'Range',range1)
filename = 'daily records.xlsx';
writematrix(Diff,filename,'Sheet',WEEK,'Range',range2)
To completely go without a switch, you could employ a Map object.
range1 = containers.Map({'Mon','Tue','Wed','Thu','Fri'},{'C10:C14','E10:E14','G10:G14','I10:I14','K10:K14'});
range2 = containers.Map({'Mon','Tue','Wed','Thu','Fri'},{'D10:D14','F10:F14','H10:H14','J10:J14','L10:L14'});
filename = 'daily records.xlsx';
writematrix(Data,filename,'Sheet',WEEK,'Range',range1(DAY))
filename = 'daily records.xlsx';
writematrix(Diff,filename,'Sheet',WEEK,'Range',range2(DAY))
But notice that I had to assume here that "otherwise" always means "Fri". You could add more keys into the map that point to 'K10:K14'.
  1 件のコメント
Jacob Holmes
Jacob Holmes 2021 年 7 月 13 日
Thanks Max. That's a much better way of doing it.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeSpreadsheets についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by