Excel Changing Variables - excel

consider that i have data in excel (B1=2, B2=5, B3=7, ... ) and ( A1=2 , A2=3)
i want to make a formula in C1 = B(A1) + B(A2) whitch result in 12 for this case
i tried B$A1 and B[A1] and B"A1" and ... all other things, not any chance
can you help me
hello
consider that i have data in excel (B1=2, B2=5, B3=7, ... ) and ( A1=2 , A2=3)
i want to make a formula in C1 = B(A1) + B(A2) whitch result in 12 for this case
i tried B$A1 and B[A1] and B"A1" and ... all other things, not any chance
can you help me

With EXCEL-365 try-
=SUM(INDEX(B1:B3,A1:A2))

Related

How to calculate formula when I create excel file in PhpSpreadsheet

I have a problem with my code. I generate an excel file unsing PhpSpreadsheet lib. So i can write my data and it worked fine. I add a data validation list in a cell using an other worksheet and it work too. So I try to add in a cell a formula which can change the value (using VLOOKUP) when someone select something in my data validation list and this work too.
But my problem is my formula is not calculated when I open my file. When I open the file I just see the formula and I wanted to see the result.
This is my code:
$i=2;
$j=6;
$filename = "export-excel.xlsx";
$spreadsheet = new Spreadsheet();
$dataSheet = $spreadsheet->getSheet(0);
$dataSheet1 = $spreadsheet->createSheet(1);
$dataSheet1->setTitle("Materiel");
$dataSheet1->setCellValue('A1','Modèle');
$dataSheet1->setCellValue('B1','Marque');
$dataSheet1->setCellValue('C1','Calibre');
$dataSheet1->setCellValue('D1','ITH');
$dataSheet1->setCellValue('E1','IMG');
$dataSheet1->setCellValue('F1','Type Matériel');
//remplissage matériel
$listMateriel = $this->entityManager->getRepository(Materiel::class)->findAll();
$nbrMateriel = count($listMateriel) +1;
foreach($listMateriel as $materiel){
$dataSheet1->setCellValue('A'.$i,$materiel->getModele());
$dataSheet1->setCellValue('B'.$i,$materiel->getMarque());
$dataSheet1->setCellValue('C'.$i,$materiel->getCalibre());
$dataSheet1->setCellValue('D'.$i,$materiel->getIth());
$dataSheet1->setCellValue('E'.$i,$materiel->getImg());
$dataSheet1->setCellValue('F'.$i,$materiel->getTypeMateriel()->getLibelle());
$i++;
}
//remplissage enveloppe
$enveloppe = $appareil->getEnveloppe();
$dataSheet->setCellValue('A5',1);
$dataSheet->setCellValue('B5',1);
$dataSheet->setCellValue('C5',$enveloppe->getLieu()->getLibelle());
$dataSheet->setCellValue('D5',$enveloppe->getNom());
$dataSheet->setCellValue('E5',$enveloppe->getNumeroschema());
$dataSheet->setCellValue('F5',$enveloppe->getCodegmao());
$dataSheet->setCellValue('G5',$enveloppe->getCodemire());
$dataSheet->setCellValue('H5',$enveloppe->getIk());
$dataSheet->setCellValue('I5',$enveloppe->getResponsable());
$dataSheet->setCellValue('J5',$enveloppe->getUnitegeo());
$dataSheet->setCellValue('K5',$enveloppe->getCentreMainteneur());
//remplissage appareil
foreach($enveloppe->getAppareils() as $app){
$dataSheet->setCellValue('A'.$j,1);
$dataSheet->setCellValue('B'.$j,2);
$dataSheet->setCellValue('C'.$j,$app->getRepere());
$dataSheet->setCellValue('D'.$j,$app->getNom());
$dataSheet->setCellValue('E'.$j,$app->getOrdreDansArmoire());
$dataSheet->setCellValue('F'.$j,$app->getMonotri());
$dataSheet->setCellValue('G'.$j,$app->getDepart());
$dataSheet->setCellValue('H'.$j,$app->getDdr());
$dataSheet->setCellValue('I'.$j,$app->getCalibreddr());
$dataSheet->setCellValue('J'.$j,$app->getMotorise());
$dataSheet->setCellValue('K'.$j,$app->getAlarme());
$dataSheet->setCellValue('L'.$j,(null === $app->getNaturealimentation()) ? '' : $app->getNaturealimentation()->getLibLong());
$dataSheet->setCellValue('M'.$j,$app->getSimultaneite());
$dataSheet->setCellValue('N'.$j,$app->getCompteur());
$dataSheet->setCellValue('O'.$j,(null === $app->getTypeconsommateur()) ? '' : $app->getTypeconsommateur()->getLibelle());
$dataSheet->setCellValue('P'.$j,$app->getTypecable());
$dataSheet->setCellValue('Q'.$j,$app->getNumcable());
$dataSheet->setCellValue('R'.$j,$app->getLongueurcable());
$dataSheet->setCellValue('S'.$j,$app->getSectioncable());
$dataSheet->setCellValue('T'.$j,$app->getMateriel()->getModele());
$this->dataValidation('T'.$j, $spreadsheet, $nbrMateriel);
$dataSheet->setCellValue('U'.$j,$app->getReglageIth());
$dataSheet->setCellValue('V'.$j,$app->getReglageImag());
$dataSheet->setCellValue('W'.$j,$app->getObservation());
//This is my formula who work fine
$dataSheet->setCellValueExplicit('X'.$j,'=SI(T'.$j.'<>"";RECHERCHEV(T'.$j.';Materiel!$A$2:$F$'.$nbrMateriel.';4;FAUX);"SO")', \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING);
$spreadsheet->getActiveSheet()->getCell('X'.$j)->getCalculatedValue();
Calculation::getInstance($spreadsheet)->disableCalculationCache();
$dataSheet->setCellValue('Y'.$j,$app->getMateriel()->getImg());
$j++;
}
$tmpPath = $this->getTmpFile2();
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xlsx');
$writer->setPreCalculateFormulas(true);
$writer->save($tmpPath);
This is what I have when I open my file:
I want to keep my formula in the cell and just show the result when I open my file. So someone have an Idea to how I can calculate my formula before to open my file ? I try with the documentation but it doesn't work.
Than in advance
The problem is that you use \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING in
$dataSheet->setCellValueExplicit('X'.$j,'=SI(T'.$j.'<>"";RECHERCHEV(T'.$j.';
Materiel!$A$2:$F$'.$nbrMateriel.';4;FAUX);"SO")', \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING);
you should use TYPE_FORMULA.
A other common problem for non calculate are string operants instead of number typ operants in the formula. If you have string typs as operant the calculation excel refuse executed by opening the formula.

Convert long formula into an ARRAYFORMULA

Document: https://docs.google.com/spreadsheets/d/1N4cGw5eUq_3gCJh1w39qVatX9KV1_Hr-AqRHj_nbckA/edit#gid=1770960621
Question
How can I convert the following simple formulas at Schedule!C20:I29 into a single, simple ARRAYFORMULA at Schedule!C20?
=Count(Filter(Students!$B$5:$B, Find(C6, Filter(Students!$J$5:$O,Students!$J$4:$O$4 = 'Current Class'!$B$3))))
.
NOTE:
The above code is only a partial solution. I will substitute the ARRAYFORMULA version of the code into the correct part of the code at Current Class!L6
The C6 reference above can take on any cell between Schedule!C6:I15. I have named that range Timetable_Code. I thought I could do the following, but I was wrong...
=Arrayformula(Count(Filter(Students!$B$5:$B, Find(Timetable_Code, Filter(Students!$J$5:$O,Students!$J$4:$O$4 = 'Current Class'!$B$3)))))
Background
Originally, I created a table that now resides at 1st Version - Current Class!L6. This tab is only for your reference and will be deleted soon. Each cell has a formula with a slight modification. This formula works correctly; however, it is a behemoth and would be hard to modify...
=if(COUNTIF(Meta!$B$5:$B, CONCATENATE("=",if(L$5 = "THURSDAY", "TH", if(L$5 = "SUNDAY", "SU", left(L$5,1))), if(left($K6, 2) = "12", 0, left($K6, 1)))), CONCATENATE(if(L$5 = "THURSDAY", "TH", if(L$5 = "SUNDAY", "SU", left(L$5,1))), if(left($K6, 2) = "12", 0, left($K6, 1)), " ( ", Count(Filter(Students!$B$5:$B, Find(CONCATENATE(if(L$5 = "THURSDAY", "TH", if(L$5 = "SUNDAY", "SU", left(L$5,1))), if(left($K6, 2) = "12", 0, left($K6, 1))), Filter(Students!$J$5:$O,Students!$J$4:$O$4 = $B$3)))), " )") ,"")
.
Pros
I don't have to create any helper data.
All calculations are "in-memory"
Cons
Too large
Hard to modify
I like the output, but I don't like the cons, so I started to create a more edit-friendly version of the code that I am mostly OK with. This code is located at Current Class!L6 (and a secondary copy at Schedule!C33 - it will be deleted.) It has a single formula at Current Class!L6...
=arrayformula(if(COUNTIF(Meta!$B$5:$B, ("=" & Timetable_Code)), (Timetable_Code & " ( " & Timetable_StudentCount & " )") ,""))
.
Pros
Very easy to understand
Very easy to modify
No need to copy formula over to other cells
Cons
Two ( 2 ) helper tables were created ( one of which I think is unneeded)
Again, I like the output, but I really don't like the second helper table (Schedule!C20). I feel like this table can be eliminated, but I have not been able to figure out how.
If you really want to use arrayformula, here it is. For Schedule!C20.
=arrayformula((len(concatenate(index(Students!J5:O, , match('Current Class'!$B$3, Students!J4:O4, 0))))-len(substitute(concatenate(index(Students!J5:O, , match('Current Class'!$B$3, Students!J4:O4, 0))),C6:I15,"")))/len(C6:I15))
Probably you can use filter(as you did before) instead of index & match part, but I prefer index & match and don't want to dig more. Also you can use one help cell to store filter or index & match result to shorten the formula.
The core idea is from counting occurrences of given character in a string, ie len(a1) - len(substitute(a1, .... You can find many documents about it in the net.
Anyway, if I were you, I'd be satified with the current state. Just lock and hide the help tables or sheets. Nobody cares hidden sheets and if something bad happens, you can revert any change.
After getting a good answer from #Sangbok Lee, I decided to break apart each part of the function he gave to me. While doing that I found a highly unlikely connection to some work I did in the Google Sheets last week. A helper column I had in another tab kind of did what Sangbok Lee was trying to do. All I had to do was split that helper column into two columns (1 for the previous final calculation, 1 for) and calculate an additional count column
After reworking both of our formulas, and testing the result, I found a solution that I am even more satisfied with!
=arrayformula(if(countif(Meta!$B$5:$B, (Timetable_Code)), (Timetable_Code & " ( " & vlookup(Timetable_Code, StudentCount_Lookup, 2, false) & " )") ,""))
.
Check out the differences in the Google Sheet
Look at 1st Version - Current Class!L6 tab for the 1st version
Look at Current Class!L6 for the 2nd version
Look at Current Class!U6 for the 3rd and final version
Also look at tab Meta and Schedule for the differences.
Note: Green is old data, Red is new data

Exporting data from cell to Excel file

Let's say I have a cell named data like this:
data{1} = vector1;
data{2} = vector2;
...
data{n} = vectorn;
All vectors (with numerical values) in data have the same 1xN size.
Now, I want to export this data file into an .xlsx document where each row is a vector and I want to label each column. The result should be something like this:
label1 label2 ... labelN
vector1(1,1) vector1(1,2) ... vector1(1,N)
... ... ... ...
vectorn(1,1) vectorn(1,2) ... vectorn(1,N)
I tried to do this using:
n=10;
N=5;
for i=1:n
data{i}=rand(1,N);
end
filename='test.xlsx';
xlswrite(filename,data)
but my .xlsx file comes with all the data from data in just one row. And I don't know how to do the labels.
Please help me.
This can be done using vertcat, num2cell, sprintf, strsplit and xlswrite as follows:
modified_data = num2cell(vertcat(data{:})); % Converting 1xn cell into nxN cell
% Generating Column Headers as specified in the question
col_header = strsplit(sprintf('label%d ' , 1:N));
col_header = col_header(1:end-1);
% If N is not much high number (e.g; if N=5), you can input Column Headers as:
% col_header = {'label1','label2','label3','label4','label5'};
filename='test.xlsx'; % Name of the excel file to be written
xlswrite(filename,[col_header; modified_data]); % Writing the excel file
Its because you call rand(1,N) together in one cell (data{i}). For each value in its own cell you have to create a nxN matrix of cells, which is easiest done if you transfrom the entire matirx:
n=10;
N=5;
data=rand(n,N);
celldata=num2cell(data);
filename='test.xlsx';
xlswrite(filename,celldata);
otherwise you have to make two loops but thats not so great performancewise

How to get MATLAB xlsread to read until a last row of a contiguous <<data-range>>?

I want to use xlsread in MATLAB to read an Excel file.
While I know which columns I want to read from, and which row I want to start reading from, the file could contain any number of rows.
Is there a way to do something like:
array = xlsread( 'filename', 'D4:F*end*' ); %% OR ANY SIMILAR SYNTAX
Where F*end* is the last row in column F?
Yes. Try this:
FileFormat = '.xls' or '.xlsx'; % choose one
% ( by default MATLAB
% imports only '.xls' )
filename = strcat( 'Filename you desire', FileFormat );
array = xlsread( filename ) % This will read all
% the Matrix ( by default
% MATLAB will import all
% numerical data from
% file with this syntax )
Then you can look to the size of the matrix to refine the search/import.
[nRows,nCols] = size( array );
Then if the matrix you want to import just parts of the matrix, you can do this:
NewArray = xlsread( filename, strcat( 'initial cell',
':',
'ColumnLetter',
num2str( nRows )
)
);
% for your case:
NewArray = xlsread( filename, strcat( 'D3', ':', 'F', num2str( nRows ) ) );
Hope this helps.
In xls format excel files, 65536 seems to be limit of number of rows that you can use. You can use this number with F and that will basically tell MATLAB to search till the end of file. That's all I could gather from little digging up work on these and this trick/hack seems to work alright.
To sum up, this seems to do the trick for xls files -
array = xlsread('filename', 'D4:F65536')
For xlsx files, the limit seems to be 1048576, so the code would change to -
array = xlsread('filename', 'D4:F1048576')
External source to confirm the limit on number of rows -
Excel versions 97-2003 (Windows) have a file extension of XLS and the
worksheet size is 65,536 rows and 256 columns. In Excel 2007 and 2010
the default file extension is XLSX and the worksheet size is 1,048,576
rows and 16,384 columns.
You could read column by column:
col1= xlsread( 'filename', 'D:D' );
col2= xlsread( 'filename', 'E:E' );
col3= xlsread( 'filename', 'F:F' );
...
Don't provide row numbers (such as D12:D465), Matlab will deal with D:D like you would expect. col1, col2 and col3 will have different sizes depending on how much data was extracted from each column.
I haven't tried something like this thought, I don't know if it would work:
colAll= xlsread( 'filename', 'D:F' );
No, But...
MATLAB does not have either documented or undocumented feature for doing this directly.
The maximum one can use under direct MATLAB support is to:
___ = xlsread(filename,-1) opens an Excel window to interactively select data.
Select the worksheet, drag and drop the mouse over the range you want,
and click OK.
This syntax is supported only on Windows systems with Excel software.
Still, how to approach the task efficiently and future-proof?
The "blind" black-box approach would be to first test the boundary of the contiguous area, where your data is present -- use any feasible iterator, first forward-stepping by doubling a blind-test step-distance of a tested cell alike aRowToTEST = ( aRowToStartFROM + aRowNumberDistanceToTEST ) and in case the tested cell contains a number, set aLastNonEmptyROW = aRowToTEST; double the aRowNumberDistanceToTEST and repeat.
In case aRowToTEST points "behind" the format-specific maximum row number, set aRowToStartFROM = aLastNonEmptyROW; and reset the forward-stepping distance aRowNumberDistanceToTEST = 1; to continue forward-stepping iterations with a doubling-step stepping. If this again hits the limit, having the step == 1 and yet pointing right "behind" the format-specific limit, your sheet-under-review contains data until its last row ( finishing on the format-specific "edge" ).
But once the target cell is empty/NaN, stop the forward-stepping phase and start a standard back-stepping phase by halving the interval between a found/failed ( empty ) cell aFirstEmptyROW = aRowToTEST; and the last known cell at aLastNonEmptyROW, that contained number.
Again, if a cell under test contained a fair value, move the aLastNonEmptyROW-boundary to aRowToTEST value, if not, move the same way aFirstEmptyROW-boundary.
Finally set aBackSteppingSTEP = ( aFirstEmptyROW - aLastNonEmptyROW )/2; aRowToTEST = aFirstEmptyROW - aBackSteppingSTEP;.
Iterate the above until your step is < 1 and thus you have iteratively found the contiguous data-area boundary.
This is way faster and incomparably more efficient than a raw-dumb-import-whole-sheet and works until both a 64k or 1M or any further upper-limit of an XLS rowNumber.
Having the boundary, simply array = xlsread( 'filename', 'D4:F<<aLastNonEmptyROW>>' );

Excel understanding SUMPRODUCT

I have a formula that uses the below SUMPRODUCT:
=SUMPRODUCT((Data!X:X = 0)* ((Data!H:H =A1)+IF(IFERROR(SEARCH(A1, Data!J:J), 0), 1, 0))* (Data!U:U = A14)(Data!M:M >= C2)(Data!N:N
<=B3))
The issue I'm having is the with the OR part:
((Data!H:H =A1)+IF(IFERROR(SEARCH(A1, Data!J:J), 0), 1, 0)).
The issue is it not working and I'm really not sure I'm going about this right. The logic I'm shooting for:
if the value in A1 equals any data in cells Data!H:H use it,
or
if not, check Data!J:J.
any help would be great.
As follow up from comments, this one work:
=SUMPRODUCT(
(Data!X:X = 0)*
(Data!U:U = A14)*
(Data!M:M >= C2)*
(Data!N:N <=B3)*
IF((Data!H:H=A1)+ISNUMBER(SEARCH(A1,Data!J:J)),1,0)
)
evaluates with CTRL+SHIFT+ENTER
SEARCH(...) reutns either number either #VALUE!, so ISNUMBER(SEARCH(...)) gives you TRUE if value found and FALSE if value not found

Resources