Matlab AppDesigner: Listbox from Excel - excel

I'm creating an app in App Designer. What I would like to do is when selecting one or multiple options, these get assigned a value of 1.
The list(i.e. "Column") is read in the following way and list options are assigned to a struct variable with a default value of 0.
table1 = readtable("file.xls");
for i = 1:length(rmmissing(table1{:,"Column"}))
s.(char(rmmissing(table1{i,"Column"}))) = 0;
end
This outputs the following table.
s.Anna = 0
s.Bett = 0
s.Cyrielle = 0
s.Dylan = 0
My problem is that I can't figure out a way of updating the value from 0 to 1, whenever I highlight one of the options. I don't know how to essentially pick up a selected value and updating it.
So as an example, If I highlight "Anna" and "Cyrielle", these should update to 1, as shown below.
s.Anna = 1
s.Bett = 0
s.Cyrielle = 1
s.Dylan = 0
I tried an if statement like. Whilst this works, it means I have to hard-code the names, which I don't want. So it needs to dynamically pick out the name that is selected.
if app.ColumnListBox.Value == "Anna"
s.Anna = 1;
else
s.Anna = 0;
end
The listbox would look like this:
Listbox
The output I get when selecting one name is:
s =
struct with fields:
Anna: 1
Bett: 0
Cyrielle: 0
Dylan: 0
However if I select multiple options, everything goes to 0:
Multiple names
s =
struct with fields:
Anna: 0
Bett: 0
Cyrielle: 0
Dylan: 0
The code now is as follows:
names = fieldnames(s);
for j = 1:numel(names)
name = names{j};
if app.ListBox.Value == string(name)
s.(name) = 1;
else
s.(name) = 0;
end
end
assignin("base","s",s)
Any help would be much appreciated!

You should be able to make your if condition less hard coded with something like
names = fieldnames(s);
for iField = 1:numel(names)
% Assign current name to variable, e.g. "Anna"
name = names{iField};
% loop over the fields and check if selected
if app.ColumnListBox.Value == string(name)
s.(name) = 1;
else
s.(name) = 0;
end

Related

Mean of one variable when another variable equals 1 in matlab

I would like to get the mean of my reaction time column when my stimnum column is equal to 1
I am not sure if i can do this with one simple line of code or if i need to do a for loop.
stimnum = randi([1 3], [1 100]);
y = 1 + 1.*randn(1, 100);
rt = (y.^2) +.01;
A = rand(1,100);
correct = A>=0.2;
Data= [stimnum; rt; correct ]';
Data = dataset({ Data, 'Stimnum', 'RT', 'Correct'});
rtmean = mean (Data.RT{Data.Stimnum == 1});

Row BGCOLOR Sets for ENTIRE Dynamic Browse, not Just 1 Row

Using the ROW-DISPLAY trigger when creating a dynamic OpenEdge browse. The problem is, when the data is displayed, all rows have the BGCOLOR determined by the data buffer's content of the LAST row only. Never had this problem with a static browse.
Browse code looks like this:
CREATE BROWSE l-browse-wh IN WIDGET-POOL "pool"
ASSIGN X = 1
Y = l-browse-y
FONT = INT(get-fn("browsedat-fnt"))
HEIGHT-PIXELS = l-h
WIDTH-PIXELS = FRAME f-data:WIDTH-PIXELS - 20
QUERY = hQuery
HIDDEN = FALSE
ROW-HEIGHT-CHARS = 0.67
READ-ONLY = FALSE
ROW-MARKERS = FALSE
SEPARATORS = TRUE
COLUMN-RESIZABLE = TRUE
COLUMN-SCROLLING = TRUE
FIT-LAST-COLUMN = FALSE
SCROLLBAR-VERTICAL = FALSE
FRAME = FRAME f-data:HANDLE
VISIBLE = TRUE
SENSITIVE = TRUE
TRIGGERS:
ON ROW-DISPLAY
PERSISTENT RUN row-color-ip IN THIS-PROCEDURE.
END TRIGGERS.
PROCEDURE row-color-ip:
DEF VAR l-bgcolor AS INT NO-UNDO.
IF tt-sold.t-exclude-sw /* <-- always uses value from last browse row */
THEN ASSIGN l-bgcolor = 8.
ELSE ASSIGN l-bgcolor = 15.
FOR EACH tt-col-handles
NO-LOCK:
ASSIGN tt-col-handles.t-wh:BGCOLOR = l-bgcolor.
END. /* of "FOR EACH tt-col-handles" */
END PROCEDURE.
It's something with your code (the part you're not showing). I used 10.2B Windows and replicated your code, filling the blanks. This little program alternates the colors, as I expected.
DEFINE VARIABLE l-browse-wh AS HANDLE NO-UNDO.
DEFINE VARIABLE hQuery AS HANDLE NO-UNDO.
define temp-table tt-sold
field cod as int
field name as char
field t-exclude-sw as logical.
create query hQuery.
hQuery:set-buffers(temp-table tt-sold:default-buffer-handle).
hQuery:query-prepare('for each tt-sold').
define temp-table tt-col-handles
field i as int
field t-wh as handle.
create widget-pool 'pool'.
define frame f-data with size 75 by 20.
CREATE BROWSE l-browse-wh IN WIDGET-POOL "pool"
ASSIGN X = 1
width = 60
height = 10
QUERY = hQuery
HIDDEN = FALSE
ROW-HEIGHT-CHARS = 0.67
READ-ONLY = FALSE
ROW-MARKERS = FALSE
SEPARATORS = TRUE
COLUMN-RESIZABLE = TRUE
COLUMN-SCROLLING = TRUE
FIT-LAST-COLUMN = FALSE
SCROLLBAR-VERTICAL = FALSE
FRAME = FRAME f-data:HANDLE
VISIBLE = TRUE
SENSITIVE = TRUE
TRIGGERS:
ON ROW-DISPLAY
PERSISTENT RUN row-color-ip IN THIS-PROCEDURE.
END TRIGGERS.
create tt-sold.
assign tt-sold.cod = 1 tt-sold.name = 'ABC' tt-sold.t-exclude-sw = yes.
create tt-sold.
assign tt-sold.cod = 2 tt-sold.name = 'DEF' tt-sold.t-exclude-sw = no.
create tt-sold.
assign tt-sold.cod = 3 tt-sold.name = 'GHI' tt-sold.t-exclude-sw = yes.
create tt-sold.
assign tt-sold.cod = 4 tt-sold.name = 'JKL' tt-sold.t-exclude-sw = no.
create tt-col-handles.
assign tt-col-handles.i = 1 tt-col-handles.t-wh = l-browse-wh:add-like-column('tt-sold.cod').
create tt-col-handles.
assign tt-col-handles.i = 2 tt-col-handles.t-wh = l-browse-wh:add-like-column('tt-sold.name').
create tt-col-handles.
assign tt-col-handles.i = 3 tt-col-handles.t-wh = l-browse-wh:add-like-column('tt-sold.t-exclude-sw').
hQuery:query-open().
l-browse-wh:refresh().
wait-for close of this-procedure.
PROCEDURE row-color-ip:
DEF VAR l-bgcolor AS INT NO-UNDO.
IF tt-sold.t-exclude-sw /* <-- always uses value from last browse row */
THEN ASSIGN l-bgcolor = 8.
ELSE ASSIGN l-bgcolor = 15.
FOR EACH tt-col-handles
NO-LOCK:
ASSIGN tt-col-handles.t-wh:BGCOLOR = l-bgcolor.
END. /* of "FOR EACH tt-col-handles" */
END PROCEDURE.
I apologize for the large chunk, but I couldn't just put my finger on where you're going wrong. Maybe this example will help you in some way. Hope it helps!

How do I only loop through certain parts of a cell array?

I am trying to figure out a way to make a for loop in which I can compare two cells that will give me two different means. One for class char and the other for class double.
This is what I have so far.
V = {2; 'tree'; 3; 'hope'};
W = {2; 'tree'; 3; 'hope'};
for i = 1:length(V);
if isequal(class(V{i}), 'double')
num = V{i}
elseif isequal(class(V{i}), 'char')
str = V{i}
end
end
for i = 1:length(W);
if isequal(class(W{i}), 'double')
acc_n(i) = isequal(V{i}, W{i})
elseif isequal(class(W{i}), 'char')
acc_s(i) = strcmp(V{i}, W{i})
end
end
mean_d = mean(acc_n)
mean_s = mean(acc_s)
The output I get is:
acc_n =
1 0 1
acc_s =
0 1 0 1
mean_d =
0.6667
mean_s =
0.5000
The output I want is:
1 1 for string, mean = 1. 1 1 for double, mean = 1
How can I do a loop where it only takes the numbers of the cell and the words of the cell separately?
Is there any possible way to only loop through the words or the numbers?
You can first extract strings and doubles and treat them separately, that will avoid loops.
V = {2; 'tree'; 3; 'hope'};
W = {2; 'tree'; 3; 'hope'};
VChar=V(cellfun(#ischar,V));
WChar=W(cellfun(#ischar,W));
acc_s=VChar==WChar;
VNum=cell2mat(V(cellfun(#isnumeric,V)));
WNum=cell2mat(W(cellfun(#isnumeric,W)));
acc_n=VNum==WNum;
Loop version: I haven't tested this but it should work.
%Assumes V and W have equal number of elements.
acc_n=[];
acc_s=[];
for i=1:numel(V)
if isequal(class(V{i}), 'double') && isequal(V{i},W{i})
acc_n=[acc_n true];
elseif isequal(class(V{i}), 'char') && strcmp(V{i},W{i})
acc_s=[acc_s true];
end
end

How to Write Value to Multiple Cells in Excel with DataNitro

I'm trying out DataNitro to automate some excel tasks, but I'm failing to grasp how to write a new value to multiple lines that relate to others,
For instance: I want it to read value from column 1, and based on a condition, to write a response in column 2.
Simplified example:
difference = CellRange((2,2),(120,2)).value
Status = CellRange((2,3),(120,3)).value
for x in difference:
if x < -10:
Status = "Paused"
###here i don't know what to put
else:
Status = "Active"
###here i don't know what to put
Thanks and sorry if the question is too stupid!
The best way to do this is to keep a counter in your loop:
difference = CellRange((2,2),(120,2)).value
# there's no need to read in the current Status value
i = 0
for x in difference:
if x < -10:
Status = "Paused"
Cell((2 + i), 3).value = "Paused"
else:
Status = "Active"
Cell((2 + i), 3).value = "Active"
i += 1
A better way to do this in Python is to use the enumerate keyword, which tracks the counter automatically:
difference = CellRange((2,2),(120,2)).value
i = 0
for i, x in enumerate(difference):
if x < -10:
Status = "Paused"
Cell((2 + i), 3).value = "Paused"
else:
Status = "Active"
Cell((2 + i), 3).value = "Active"

match check in matlab

i have strings like these:
s{1,2} = 'string';
s{2,2} = 'string2';
and in workspace structure like this
U.W.string = [2 2.5 3]
I want to check (in loop) s{1,2} or s{2,2} or s{i,2} matches any structure with the same name. If so, assign values from this structure to some variable var(i). How can it be done?
Use isfields to check, if a string is the name of a field in a struct. Then use the syntax struct.(name), where name is a string to access the field. Your code might look something like:
test = struct('hello', 'world', 'count', 42, 'mean', 10);
fields = {'test', 'count';
'hello', 'text';
'more', 'less'};
values = {pi, 'dummy', -1};
for row = 1 : size(fields, 1)
for column = 1 : size(fields, 2)
if isfield(test, fields{row, column})
test.(fields{row, column}) = values{row};
end
end
end
This converts the initial struct
test =
hello: 'world'
count: 42
mean: 10
to this one
test =
hello: 'dummy'
count: 3.1416
mean: 10
A shorter implementation is achieved by removing the inner loop and giving a cell-array to isfields:
for row = 1 : size(fields, 1)
%# Note the parenthesis instead of curly braces in the next statement.
match = isfield(test, fields(row, :));
if any(match)
test.(fields{row, match}) = values{row};
end
end
Use isfield(structName,fieldName). This should do the trick:
strings{1,1} = 'foo';
strings{1,2} = 'bar';
strings{1, 3} = 'foobar';
U.W.foo = 1;
U.W.foobar = 5;
for idx = 1:length(strings)
if(isfield(U.W,strings{1,idx}))
expression = sprintf('outvar(idx) = U.W.%s',strings{1,idx});
eval(expression);
end
end

Resources