How to Write Value to Multiple Cells in Excel with DataNitro - excel

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"

Related

Replace not working with SAP Gui Scripting retrieved data

So I created a scripting to retrieve data from SAP Gridview object to an Excel sheet. Some columns I needed to replace some characters because this data is consumed by a Power Bi report. For example:
4,350.00 will be replaced for the value 4350. So I do two replaces, the first removing the . and the second replacing the , with .
The problem is that the replace is being applied in every data retrieved. Here's the code.
For i = 0 To GridView.RowCount - 1
For j = 0 To GridView.ColumnCount - 1
shtInput.Cells(z + i, j + 1) = GridView.GetCellValue(i, GridView.ColumnOrder(j))
If j > 8 And j < 19 Then:
rep = GridView.GetCellValue(i, GridView.ColumnOrder(j))
rep = replace(rep, ".", "")
rep = replace(rep, ",", ".")
shtInput.Cells(z + i, j + 1) = rep
Next j
shtInput.Cells(z + i, Area) = "Finance"
If i Mod 32 = 0 Then
GridView.SetCurrentCell i, CStr(Columns(0))
GridView.firstVisibleRow = i
End If
Next i
There's a data column that the script capture the value 21.02.2021 and replace it with 21,02,2021.

Matlab AppDesigner: Listbox from 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

Grading system in excel sheet based on marks

I am trying to paste grades in excel sheet based on marks
i do this but this shows only F in excel sheet .. i want if anybody has marks >=80 then want to show A grade .. and if anybody hay >=70 then B
and if anybody have less than 70 then want to show F
UPDATED CODE
clc,clear all
filename = 'PROJECT..xlsx';
table = readtable(filename);
data = xlsread(filename);
[r,c] = size(data);
total_courses = c;
table.SumofMarks = zeros(r,1);
table.Percentage = zeros(r,1);
table.StudentGrade = repmat({''},r,1);
% Sum of marks in different courses and their percentage.
format bank
Sum_of_Marks = sum(data,2);
Student_Percentage = Sum_of_Marks./total_courses;
T = horzcat(Sum_of_Marks,Student_Percentage);
N = length(Student_Percentage);
table.SumofMarks = Sum_of_Marks;
table.Percentage = Student_Percentage;
for i = 1:63
sheet1=readtable(filename);
mark=sheet1{i,{'CALCULUS','DISCRETE','ECONOMICS','ISLAMIAT','STATISTICS'}};
if mark(mark<40)
grade='F';
sheet1(i,'StudentGrade')=cellstr(grade);
else
continue
end
end
writetable(table,filename)
xlswrite(filename,T,1, 'H2')
xlswrite(filename,grade,1,'J2')
these are the errors which I get
Error using getRowIndices (line 75)
Row index exceeds table dimensions.
Error in table/subsrefBraces (line 17)
[rowIndices,numRowIndices] =
getRowIndices(t, s(1).subs{1});
Error in table/subsref (line 60)
[varargout{1:nargout}] =
subsrefBraces(t,s);
Error in lab4 (line 38)
mark=sheet1{i,{'CALCULUS','DISCRETE','ECONOMICS','ISLAMIAT','STATISTICS'}};
i tried this but this code doesnt work
how i do this
i paste link where my file is located.. and I want if any student get less than 40 marks in any subject then want to show F grade.. this code shows if total marks is less than 40 .. where as I want to show if marks is less than 40 in any subject
this is the excel file
https://drive.google.com/file/d/1VQ8XxAQPu6reY0SCNV9Rxt65w1koduGA/view?usp=sharing
I don't have Excel installed, so I can't check the part about reading and writing to Excel, but you should replace
if R>=80
table.StudentGrade{i} = 'A';
elseif R>=70
table.StudentGrade{i} = 'B';
elseif R <70
table.StudentGrade{i}= 'F';
end
with
if R(i)>=80
table.StudentGrade{i} = 'A';
elseif R(i)>=70
table.StudentGrade{i} = 'B';
elseif R(i) <70
table.StudentGrade{i}= 'F';
end

Why am I not getting an expected output using logical operators and indexing?

I am having trouble achieving an expected output. I am trying to create a byte adder using logical operators such as AND, XOR and OR. I have taken the minimal code required to reproduce the problem out of code, so assume that finalfirstvalue = "1010" and finalsecondvalue = "0101".
secondvalueindex = (len(finalsecondvalue) - 1)
carry, finalans = False, []
for i in range(-1, -len(finalfirstvalue) - 1, -1):
andone = (bool(finalfirstvalue[i])) & (bool(finalsecondvalue[secondvalueindex]))
xorone = (bool(finalfirstvalue[i])) ^ (bool(finalsecondvalue[secondvalueindex]))
andtwo = (bool(carry)) & (bool(xorone))
xortwo = (bool(carry)) ^ (bool(xorone))
orone = (bool(andone)) | (bool(andtwo))
carry = (bool(orone))
finalans.append(xortwo)
secondvalueindex -= 1
answer = ''.join(str(e) for e in finalans)
print (answer)
Actual Output: FalseTrueTrueTrue
Expected Output: TrueTrueTrueTrue
The code then follows to change back into zeroes and ones.
Because its missing a single boolean I feel like the issue is with my indexing. Although I've played around with it a bit and not had any luck.
I need to carry out these operations on the two variables mentioned at the start, but for the right most elements, and then move to the left by one for the next loop and so on.
First mistake is You are representing your binary numbers as string values.
finalfirstvalue = "1010"
finalsecondvalue = "0101"
secondvalueindex = (len(finalsecondvalue) - 1) == 3
So in second for loop you will get the result as
(finalsecondvalue[secondvalueindex]) == '0'
If you check in your Idle
>>> bool('0')
True
>>>
Because '0' is not actual 0 it is an non-empty string so it return True.
You need to cast your result to int before checking them with bool
Like this
(bool(int(finalsecondvalue[secondvalueindex])))
EDIT 2 Adding with variable lenghts
Full adder with verification using bin() function
a="011101"
b="011110"
if a>b:
b=b.zfill(len(a))
if a<b:
a=a.zfill(len(b))
finalfirstvalue = a
finalsecondvalue = b
carry, finalans = 0, []
secondvalueindex = (len(finalsecondvalue))
for i in reversed(range(0, len(finalfirstvalue))):
xorone = (bool(int(finalfirstvalue[i]))) ^ (bool(int(finalsecondvalue[i])))
andone = (bool(int(finalfirstvalue[i]))) & (bool(int(finalsecondvalue[i])))
xortwo = (carry) ^ (xorone)
andtwo = (carry) & (xorone)
orone = (andone) | (andtwo)
carry = (orone)
finalans.append(xortwo)
finalans.reverse()
answer=(''.join(str(e) for e in finalans))
print(str(carry)+answer)
print(bin(int(a,2) + int(b,2))) #verification
So I found the issue was to do with carry. I changed my code to look like the following. Prior to this code below, is code to convert binary values to boolean. For instance, all ones will equal True and all zeroes will equal False.
carry, finalans = False, []
indexvalue = (len(finalfirstvalue)-1)
while indexvalue >= 0:
andone = (firstvaluelist[indexvalue]) & (secondvaluelist[indexvalue])
xorone = (firstvaluelist[indexvalue]) ^ (secondvaluelist[indexvalue])
andtwo = (carry) & (xorone)
xortwo = (carry) ^ (xorone)
orone = (andone) | (andtwo)
carry = (orone)
if (carry == True) & (indexvalue == 0):
finalans.append(xortwo)
finalans.append(True)
else:
finalans.append(xortwo)
indexvalue -= 1
for n, i in enumerate(finalans):
if i == False:
finalans[n] = "0"
if i == True:
finalans[n] = "1"
finalans.reverse()
answer = ''.join(str(e) for e in finalans)
print (answer)
So if there was a single value missing, it was still stored in carry from the final loop but did not get the opportunity to be appended to the final result. To fix this, I added in an if statement to check if carry is containing anything (True) and if the loop is on its final loop by checking if indexvalue is at 0. This way, if the inputs are 32 and 32, rather than getting [False, False, False, False, False, False] as the output, the newly entered if statement will add the missing value in.

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

Resources