I checked a lot of topics on stack's about my issue, but every resolution don't work for me.
So please help me with two things.
1) I want to delete column 'M'.
I checked $excelObj->getActiveSheet()->removeColumn('M'); (Doesn't work)
2) I have got a bit of code:
//ISP MCR FULLAUTOMAT
for ($row = 1;$row <= $lastrow; $row++) {
if(strpos(($worksheet->getCell('K'.$row)->getValue()), $orion_automat) !== false) {
if((strpos(($worksheet->getCell('J'.$row)->getValue()), $mcr_isp_full) !== false) and
(strpos(($worksheet->getCell('J'.$row)->getValue()), $mcr_isp_full_anal) == false)) {
$full++;
}
}
}
After the $full++; I want to make something like that:
If script will add +1 to $full, he will also write 1 in the column "N" in a $row.
I tried this:
$excelObj->getActiveSheet()->setCellValue('N'.$row, '1');
And this:
$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow('N', $row, '1');
If someone has got a little bit time to help, please write what I can try more.
Thank you.
Yours faithfully - Mariusz Adamczewski
Related
I am writing some if conditions in excel and i don`t succeed. I would glad if you can help me.
I want to write the following if condition(Pseudo code):
If(L28 appears between C44:C47)
{
Value = D31
}
else if( L28 ==C48)
{
Value = D32
}
If(L28 appears between C49:C53)
{
Value = D30
}
else If(L28 appears between C54:C57)
{
Value = D29
}
else
{
Value = L28
}
I have written the following part of code, but it is does not work.
"=IF(COUNTIF(C44:C47,L28),D31,if(L28=C48,D32,if(COUNTIF(C49:C53,L28),D30,if(COUNTIF(C54:C57,L28),D29))))"
Well, try this, but I have not tested it:
=if(iferror(match(L28,C44:C47,0),0)>0,D31,if(L28=C48,D32,if(iferror(match(L28,CC49:C53,0),0)>0,D30,if(iferror(match(L28,C54:C57,0),0)>0,D29,L28))))
Excel has a new ifs() function in one of the latest updates.
ifs(condition1, value1, condition2, value2,...) outputs the value for the first condition that is true.
that could simplify the formula a bit. No more need for nested if(). Below is Solar Mikes solution with ifs().
=ifs(iferror(match(L28,C44:C47,0),0)>0,D31,L28=C48,D32,iferror(match(L28,CC49:C53,0),0)>0,D30,iferror(match(L28,C54:C57,0),0>0,D29,L28)
I am using the EPPlus library in my ASP.Net application.
What I am trying to do is open a spreadsheet, input some values into cells and then read another cell which contains the result of a calculation. The spreadsheet itself is confidential so I can't provide many details on it.
In order to get my calculations to work I have had to modify the source code for EPplus, changing the Compile function in the ExcelAddressExpression.cs file to ignore the ParentIsLookupFunction bool as shown at the bottom of the question.
so it was able to evaluate the term 5*$f$7
What I want to know is what situations is it useful to keep the CompileResult as an ExcelAddress, so I do not run into any incorrect calculations or errors in other parts of the spreadsheet.
For reference here are the steps I went though to get here:
My code is something like this
using (ExcelPackage p = new ExcelPackage(FilePath, true))
{
ExcelWorksheet ws = p.Workbook.Worksheets["Calculations"];
ws.Cells["b7"].Value = 50;
ws.Cells["f9"].Value = 500000;
ws.Cells["j216"].Calculate();
string result = ws.Cells["j216"].Value.ToString();
}
The formula in cell J216 is
=VLOOKUP($B$7+$F$221+$K$13-$F$8-1,Sheet2!$A$4:$T$103,5*$F$7+2*$B$8+$B$9-5,FALSE)
and the result I got was '#VALUE!'
I have attached a log file and found the issue is in the VLookup function
Worksheet: Calculations
Address: J216
OfficeOpenXml.FormulaParsing.Exceptions.ExcelErrorValueException: #VALUE!
at OfficeOpenXml.FormulaParsing.Excel.Functions.IntArgumentParser.Parse(Object obj)
at OfficeOpenXml.FormulaParsing.Excel.Functions.RefAndLookup.LookupArguments..ctor(IEnumerable`1 arguments, ArgumentParsers argumentParsers, ParsingContext context)
at OfficeOpenXml.FormulaParsing.Excel.Functions.RefAndLookup.VLookup.Execute(IEnumerable`1 arguments, ParsingContext context)
at OfficeOpenXml.FormulaParsing.ExpressionGraph.FunctionCompilers.LookupFunctionCompiler.Compile(IEnumerable`1 children, ParsingContext context)
at OfficeOpenXml.FormulaParsing.ExpressionGraph.FunctionExpression.Compile()
The next step I took was to download the source code for EPPlus, and debug through the code as it executed, eventually finding the problem was at line 165 of Operator.cs
l = l ?? new CompileResult(0, DataType.Integer);
r = r ?? new CompileResult(0, DataType.Integer);
if (l.DataType == DataType.Integer && r.DataType == DataType.Integer)
{
return new CompileResult(l.ResultNumeric*r.ResultNumeric, DataType.Integer);
}
else if ((l.IsNumeric || l.IsNumericString || l.IsDateString || l.Result is ExcelDataProvider.IRangeInfo) &&
(r.IsNumeric || r.IsNumericString || r.IsDateString || r.Result is ExcelDataProvider.IRangeInfo))
{
return new CompileResult(l.ResultNumeric*r.ResultNumeric, DataType.Decimal);
}
return new CompileResult(eErrorType.Value);
When evaluating the equation 5*$F$7, the second parameter was of DataType ExcelAddress which is results in a compile result exception being thrown.
The root cause of this is in the Compile function of the ExcelAddressExpression.cs file the ParentIsLookupFunction boolean controls whether the cell is evaluated or left as an address.
public override CompileResult Compile()
{
if (ParentIsLookupFunction)
{
return new CompileResult(ExpressionString, DataType.ExcelAddress);
}
else
{
return CompileRangeValues();
}
}
I have modified my version of the code to simply be
public override CompileResult Compile()
{
return CompileRangeValues();
}
As said at the top of the question, what I want to know is why would you want to return the ExcelAddress CompileResult, It was obviously put there for a reason and I do not want to break some other calculations in my spreadsheet.
I can confirm though that for at least this calculation it is now working correctly.
I wrote the formula engine of EPPlus some years ago, but don't work much on the project these days. If I recall it correctly there are cases where you don't want to compile the excel address in the expression, but rather pass it on to the executing function. Have you tried to run the unit tests? The formula engine is covered by hundreds of tests and the test result could provide some guidance.
I was able to answer this after experimenting with different spreadsheets.
Returning the value as an ExcelAddress is useful in the event that the address is not operated on like in my earlier example 5*$F$7 such as an IF statement inside a VLookup.
In the event that there is an operator you will want to return the contents of the cell.
I modified the EPPlus code to now check for any operators separating terms in the formula
public override CompileResult Compile()
{
if (ParentIsLookupFunction &&
Operator == null &&
(Prev == null || Prev.Operator == null))
{
return new CompileResult(ExpressionString, DataType.ExcelAddress);
}
else
{
return CompileRangeValues();
}
}
Now I get a ComboBox control, everything is OK except that:
firstly, I selected one in a multiple-selection list box, works;
secondly, I edit the selected text, no update,
thirdly, I edit again then changed as I wanted.
At my program, every time selecting and editing would call a function named ChangeControlNotify(ClistControl* pControl) and there is a GetTest() in this function. The problem occurred at that function GetTest() because it calls CComboBox::GetCurSel. GetCurSel function should return -1 at first time edit, but it returns the selecting line number as that firstly selecting.
Does anyone know why? I think maybe there is still a handler reminding after firstly editing. But I don't know and have no idea yet. If some kindly guys help. very aprreciate. Thanks
_bstr_t CComboBoxListControl::GetText()
{
CComBSTR bstr;
int nSel = m_comboBox.GetCurSel();
if ((-1 == nSel) && ((m_comboBox.GetWindowLong(GWL_STYLE) & CBS_DROPDOWNLIST) != CBS_DROPDOWNLIST))
{
m_comboBox.GetWindowText(&bstr);
}
else
{
m_comboBox.GetLBTextBSTR(nSel, bstr.m_str);
}
return bstr.m_str;
}
template <bool bIsCheckListView>
void CRichListControls<bIsCheckListView>::ChangeControlNotify(CListControl* pControl)
{
CListPosition lp = FindControlPosition(pControl);
SetItemText(lp.GetLine(), lp.GetColumn(), pControl->GetText(), false);
CRichListControlData data(m_hWnd, lp);
SendMessage(m_wndContained.m_hWnd,
WM_RICHLISTCONTROLS_MESSAGE,
WPARAM(rmtModify),
reinterpret_cast<LPARAM>(&data));
}
I have stringfilters bind to my table of data.
What i would like to get from the stringfilter is to be able to search like you would do with queries.
There is a colomn with names - a name for each row - for example - "Steve","Monica","Andreas","Michael","Steve","Andreas",...
I want to have both rows with Monica and Steve from the StringFilter.
I would like to be able to search like this
Steve+Monica
or
"Steve"+"Monica"
or
"Steve","Monica"
This is one of my stringfilters:
var stringFilter1 = new google.visualization.ControlWrapper({
controlType: 'StringFilter',
containerId: 'string_filter_div_1',
options: {
filterColumnIndex: 0, matchType : 'any'
}
});
I had a similar problem, and I ended up creating my own function for filtering my rows. I made an example with the function that you describe, but I'm not sure it's the best or the right way, but it works.
One flaw is that you need to type in the names exactly as they are entered, the whole name and with capital letters.
Fiddle, try to add multiple names separated with a "+" (and no spaces).
The function I added looks like this:
function redrawChart(filterString) {
var filterWords = filterString.split("+")
var rows = []
for(i = 0; i < filterWords.length; i++) {
rows = rows.concat(data.getFilteredRows([{value:filterWords[i], column:0}]))
}
return rows
}
And the listener that listens for updates in your string input looks like:
google.visualization.events.addListener(control, 'statechange', function () {
if (control.getState().value == '') {
realChart.setView({'rows': null})
}else{
realChart.setView({'rows': redrawChart(control.getState().value)})
}
realChart.draw();
});
Probably not a complete solution, but maybe some new ideas and directions to your own thoughts.
I have four fields. Lets call them a, b, c and d. I need to validate them.
Error is when:
One til three fields are not empty;
Error is not when:
All fields are not empty,
All fields are empty;
Any neat solution here? Thanks in advice.
Edit:
Only relationships are that all four variables are prefixed with event_. It gives me event_name, event_description etc..
Edit #2:
At the moment I have something like...
if (
!empty($values['event_date'])
&& !empty($values['event_time'])
&& !empty($values['event_name'])
&& !empty($values['event_description'])
) {
It checks that all fields are filled up and then, if that's true, adds event.
As I said before, I need to display user-friendly error when some field isn't filled up (for example, user had forgot to enter description). Anyway, when all fields are filled up (it means - all okay) or when no fields are filled up (it means - user ignores event adding and don't want to add one) - no error should be displayed.
I could write code with 16 'if' statements, but isn't there any better way? :)
This isn't beautiful, but as long as you have something unique about the fields you want to check (such as "event_..."), you could loop through the variable array ($values, $_POST, etc) and check only the fields that matter. Then, you can easily check for an all or none situation.
Here is a quick example:
$total = 0;
$filled = 0;
foreach($values as $field => $val) {
if(strpos($field,'event_') === 0) {
$total++;
if( ! empty($val)) {
$filled++;
}
}
}
if($filled == 0 OR $total == $filled) {
//PASS VALIDATION
} else {
//FAIL VALIDATION
}
Is there a relationship between one of the entered values and the none entered values??
could you just parse it as an empty value?
if ( ! isset($post->a) ) $post->a = '';