Using Xlswrite for cell array - excel

I understand that the xlswrite cannot directly populate the contents of the cell array to the excel sheet. Somehow I'm missing a logic in my code where I need to populate every single element exported to a sheet. say my cell array has cells in it and characters example
Names = (1x1 cell) (1x1 cell) (1x1 cell) (1x1 cell)
or say
Names= {{'Brian'};{'Andy'};{'Katherine'};{'crystal'};{'Thomas'};{'Michael'}; {'Maria'}.........};
tried xlswrite directly but it didn't work. Understood the point that it can print one at a time (correct me if im wrong).
saveto = 'D:\Data\';
xlswrite([saveto,'test'],Names{1},'A1');
would work only for one element in cell. Writing a for loop is not helping me as well
for aa=1:length(Names)
saveto = 'D:\Data\';
xlswrite([saveto,'test'],Names{aa},'A1:A2000'); % A2000 is used as a random number
end
your help is appreciated.

Try to "flatten" your Names before writing to the xls:
Names= {{'Brian'};{'Andy'};{'Katherine'};{'crystal'};{'Thomas'};{'Michael'};{'Maria'}}
NamesToWrite = reshape([Names{:}], size(Names));
then use xlswrite on NamesToWrite:
saveto = 'D:\Data\';
xlswrite([saveto,'test.xls'],NamesToWrite);
This happens because, if you pass a cell array to the function, its elements need to be either numeric scalars or strings.

Related

Excel - Comparing Strings within Two Cells

NEW IMAGE Updated - CLICK ME!
I am comparing two corresponding columns of data in excel. This is just my example simplified. In the first row, it passes because A and B are in column 2. It does not have to contain C, but it can only be any of the letters contained in cell 1:1. For row three, it does not pass because A is not an option within cell 3:1. What conditional formatting would I do for a large data set
You could try:
Conditional formatting rule for A1:B3:
=ISERROR(SUMPRODUCT(FIND(" "&FILTERXML("<t><s>"&SUBSTITUTE($B1," ","</s><s>")&"</s></t>","//s")&" "," "&$A1&" ")))
But since conditional formatting is volatile I don't know if it's wiser to use conditional formatting or just apply the formula to a 3rd column if you are using it on a large dataset. Up to you.
As you might need to run through all entries within one cell, I'm afraid that you might need VBA for solving this one. It would mean that you write an UDF (User-Defined Function) for doing the checking and use that as a basis for a formula for your conditional formatting.
Your function should be something like (not tested):
Function chars_inside_string(characters, inside_string) As Boolean
Dim present As Boolean
present = True
test = Split(characters, "-")
For i = 1 To UBound(test)
present = present AND (InStr(test(i), inside_string) > 0)
Next i
chars_inside_string = present
End Function

Retrieve ranges instead of Strings from array formula result in Excel

Having the nest Formula:
"=IF(Hoja1!$A$4=$A$15:$A$22),IF($B$4=$B$15:$B$22),IF($F$15:$F$22=0,$A$15:$A$22)))"
The resulting array is like so:
{FALSE\FALSE\FALSE\FALSE\FALSE\"Title 6"\FALSE\FALSE}
get an array that is set of booleans, and in this case I get String, but what I want to get is Ranges so I can know the position of that gotten non False result in the resulting array.
I know I could do the same using loops in VBA but my goal was to make it using formulas.
I don't know, maybe there is some built-in function that retrieves ranges that I don't know of.
Alternatively, I thought that having a known Range like $A$15:$F$22 I could get the index numbers of the resulting array that has a non false value and make a Range.Cells(index1, index2) using the 2 indexes of the array.
Also, I thought that using the MATCH function could do it.
For example
Match(<>False, {false\"string value"},0)
And so retrieve the row number that I can then use in a .Cell().
But It does not work. Can I do also a excluding match?
What do you suggest? Any easy/fast solution for this?
Reference to get the date:
Data source
I found a solution that was almost in front of my eyes.
I haven't tried using more than one possible search in an array constant (result of an aray formula).
It works for sure in array constant results that has one non empty/non-false results.
Using MATCH() was the solution.
Using the previous conditional formula I got an array with all results FALSE, except for one. Since the non empty/false result is a String and I want to know what is the range that result is in, using the data source range I extract that cell using the row index taken from the MATCH function, and then with simple VBA I have the range I wanted, like so.
Dim F As String
Dim Res As Integer
Dim R As Range
Set R = Range("$A$15:$A$22")
F = "=MATCH($A$4,IF($A$4=$A$15:$A$22),IF($B$4=$B$15:$B$22),IF($F$15:$F$22=0,$A$15:$A$22)))),0)"
'We get the index number of the desired value in the array that
we got in *IF* parts of the array formula.
Res = Hoja1.Evaluate(F)
'Since The position in the array of the element we want is the same as the row number inside the range the value we searched for is in, we can get that range/cell easily.
Set R = R.Cells(Res, 1) 'Or the column I want.
Debug.Print R.Address
The result is $A$18.
As we expected it matches, since inside the $A$15$:$A$22 the value we looked for is in the 4th row inside that source range.
We can get other columns for that match as well.

how can I access cells in excel sheet using only numbers without alphabets like A1 or B2

I'm writing Matlab script to access data from excel sheet. I don't want to access cell using alphabets (e.g. B1). But I'm unable to access cell using cell(row,column).
Could anyone help me out?
This set of functions will convert any number to its equivalent Excel column:
Cletter = #(c) char(mod(c,26)+(mod(c,26)==0)*26+64);
AZbase = #(c) fliplr(cumprod([c repmat(1/26,1,2)]));
xlCOL = #(c) Cletter(nonzeros(floor((AZbase(c)-circshift(mod(AZbase(c),26)==0,-1)).*(c>[702 26 0]))).');
You can combine them to one function, but I prefer to leave them separated so it won't be too hard to understand how they work.
For example:
>> xlCOL(6504)
ans =
'IPD'
Now you can extend them with another pair of functions to build the range string:
RC2AB = #(row,col) [xlCOL(col) int2str(row)];
makeRange = #(c1,c2) [RC2AB(c1(1),c1(2)) ':' RC2AB(c2(1),c2(2))];
(again, I prefer to leave them separated...)
for example:
>> makeRange([12,321],[46,951])
ans =
'LI12:AJO46'
Note the in makeRange the input is two 2-element vectors, one for the first cell in range and one for the last. In each cell, the first element is the row, and the second is the column.
You can verify this result using the formula ADDRESS(row_num, column_num) in Excel.
This is only for simple use. It does not perform any checks that this is a valid range (i.e. that the second cell is not above/left to the first cell and that the column/row number is not out of range).
I took this question more as a challenge than as a real problem. There is no doubt that writing a small m-file with a function (like in the linked answer) would be more simple. But I had to find a way to complete this in a few anonymous functions.
Still, this answer does not provide any explanation on how they work, as I don't think that someone will be interested in it, but if you do - just leave a comment, and I'll add some explanations.

Applescript get all values of Excel column

I am trying to store all the values of an excel column in an array.
set rangeDate to {value of range "A14:A100"}
repeat with date in rangeDate
if (date as string is equal to "01/01/2001") then
log "It works"
end if
end repeat
In my Excel I do have an exact date of 01/01/2001 formatted in the specified columns. When I remove the range and it is just cell A14 (where the date is) it works. But when I include the range A14:A100 it doesn't work.
I am new to applescript, I guess that it doesn't store the values as array values and instead a string object? Any help would be appreciated
You have 4 issues :
1) value of range should not be between {}, but between ()
2) 'Date' is a reserved word in Applescript, so you should not use it as the variable in the loop. I replaced it with 'myDate'.
3) instead of converting your date to string to compare with "01/01/2001", it is quicker to keep comparing 2 dates, and then, compare with the date "01/01/2001"
4) I think it is a bug (at least with my Excel version), but the rangeDate variable is not a list of dates as expected, but for me a list of list : {{01/02/01},{02/02/01},………} Therefore, each member of 'rangeDate' is not a date, but a list made on one item which is a date ! I am not sure, but it could also be that range definition could be a list of ranges... So I am using item 1 of sub list.
Anyway, script bellow is working :
tell application "Microsoft Excel"
activate
tell active sheet of document 1
set rangeDate to (value of range "A14:A100")
repeat with mydate in rangeDate
set TheDate to item 1 of mydate
if TheDate = (date "lundi 1 janvier 2001 00:00:00") then
log "It works"
end if
end repeat
end tell
end tell
Quickly getting the values of a range of cells is great news! But even better is that you can fill in the values of a range by defining the value of that range. This is SO MUCH FASTER than doing it one cell at a time.
When I tried getting the value of a column (a range of cells), I received a list of lists. Each item in the list had only one value - that is the value of the cell.
To speed up complex operations, once you've got the list of values, take the process out of the "tell Excel" block and let AppleScript do the calculations. Then turn the result back into a list of lists and define the value of the range in Excel.
I had a problem reading ranges with some cells containing #VALUE! (failed formulas). I didn't find a solution on the Internet, so I thought it would be a good idea to share my solution here. Comments & improvement are surely welcome. I'm inclined to think there is a more straightforward solution to the problem than this. :)
Getting all values with value of range can lead to a problem messing up the output of the script. AppleScript doesn't consider a cell's content "#VALUE!" (= missing values) a value since it is, well, missing. Therefore the script doesn't include the cell's content in the list of values. This obviously messes up the cell order in the values list, since it has less items than the actual range has cells. In this situation it is quite impossible to return each value to its original cell in the workbook. Adding ”of ranges” to the code includes all cells with missing values solving the problem.
N.B. The values will be displayed as a one-dimensional array. Handling multi-column ranges requires more work. Nonetheless the missing values are included.
set celVals to (value of ranges of range "A1:A4")
E.g. {2.2.2022, 1.1.2011, missing value, 3.3.2033}
In order to return the values back to the workbook it is required to build back the list of lists. A missing value will be written to its cell as an empty string. Of course the original (failed) formula can be written instead, if needed.
N.B. again. This code applies to one column situation only. A little more is needed to put back a multi-column range. I'm sure you'll manage. :D
set returningCelVals to {}
repeat with i from 1 to count of celVals
set end of returningCelVals to {item i of celVals}
end repeat
set value of range ("A1:A4") to returningCelVals
EDIT: I knew there is a better solution. Here it is:
set celVals to string value of range "A1:A4"
String value gives a two-dimensional array of values and error messages of the range. String value gives also e.g. cell's currency symbols, so it is perhaps not suitable to all situations.

Writing a cell array of strings to Excel from Matlab?

I want to write the names of genes into excel but when I run this code matlab doesnt write anything into excel. The cells I want filled are left blank. I cant seem to figure out what I am missing in my code. names is a cell array of string names.
function nameWriter()
x = importdata('mitominerratmitochondrialoutermembraneproteins');
names = {};
n = length(x.textdata);
counter = 0;
for i = 1:n
if strncmp(x.textdata(i),'>', 1) ==1
names{end+1} = x.textdata(i);
counter = counter +1;
end
end
xlswrite('aacount2.xls', names, 'B1:CB1');
end
I believe the likely source of your error is that you are not taking into account that x.textdata is going to be a cell array of strings (as described in the table in the IMPORTDATA documentation for the output argument A). When you assign data to names like so:
names{end+1} = x.textdata(i);
You are actually placing a cell array inside another cell array, and XLSWRITE apparently can't handle nested cell arrays (i.e. it outputs blank fields for cell elements of the input that contain cell arrays). You should instead use curly braces, not parentheses, to access the cell contents of x.textdata, like so:
names{end+1} = x.textdata{i};

Resources