Formula in Excel - Logarithmic Average - c#

I need to implement this equation:
In c# it is pretty straightforward:
static double LogarithmicSummed(IReadOnlyList<double> values)
{
double outVal = 0;
for (int i = 0; i < values.Count; i++)
{
outVal = outVal + Math.Pow(10, values[i] / 10);
}
return 10 * Math.Log10(outVal);
}
I need to verify the data in an excel sheet where I print out the data programmatically. That is the raw data, my c# calculations on the raw data AND the excel formual that should match my c# calculations. I just do not know how to write the formula in excel.
I know the rows and columns where the data are and they are next to each other. So for example, if I needed the arithmetic average, ie:
I could print out for each row:
// If row = 1, startColumn = A, endColumn = D, noOfColumn = 4. This would print: =SUM(A1:D1)/4
mean[row] = #"=SUM(" + startColumn + row + ":" + endColumn + row + ")/" + noOfColumns;
What would I print out to match the first formula I wrote? Or what would I need to write in Excel?

without VBA:
Put your data in A1 through A10 and in B1 enter:
=10^(A1/10)
and copy down. Then in another cell enter:
=10*LOG10(SUM(B1:B10))
You can avoid the "helper" column (column B) by using:
=10*LOG10(SUMPRODUCT(10^((A1:A10)/10)))

If that's how you enter your formulas, then why not use the literal form of the sum? Ie use a for loop over the columns and fill in:
10*log(10^(A1/10)+10^(A2/10)+10^(A3/10)+10^(A4/10))

Related

Writing into word document with different font sizes, etc

I am trying to pick string values from different Excel worksheets and write it into Word. However, each text line will have different font size, bold and underline.
I managed to pull all values into Word with StringBuilder, however I am not able to format each line way I wanted, therefore trying to make other solution without StringBuilder.
Please see code below. Unfortunately, the end result has only the last row of Excel sheet value.
Anyone has idea, what I can do here:
for (int c = 0; c < aList.Count; c++)
{
Worksheet excelWorksheet = excelWorkbook.Worksheets[aList[c]];
Microsoft.Office.Interop.Excel.Range lastRow = excelWorksheet.Cells.SpecialCells(XlCellType.xlCellTypeLastCell);
int lastUsedRow = lastRow.Row;
currentItemNumber = "Item " + (c + 1).ToString();
docRange.Text = currentItemNumber;
docRange.Font.Bold = 1;
docRange.Font.Size = 12;
docRange.Font.Underline = (WdUnderline)1;
docWholeRange.Text = docRange.Text;
for (int d = 0; d < lastUsedRow; d++)
{
if (d == 0)
{
currentRowValue = excelWorksheet.Range["A" + (d + 1)].Value2 + "\t" + excelWorksheet.Range["D"+(d+1)].Value2;
docRange.Text = currentRowValue;
docRange.Font.Bold = 0;
docRange.Font.Size = 12;
docRange.Font.Underline = (WdUnderline)0;
docWholeRange.Text = docWholeRange.Text + docRange.Text;
}
else
{
currentRowValue = excelWorksheet.Range["A" + (d + 1)].Value2+ excelWorksheet.Range["B" + (d + 1)].Value2+ excelWorksheet.Range["C" + (d + 1)].Value2;
docRange.Text = currentRowValue;
docRange.Font.Bold = 0;
docRange.Font.Size = 10;
docRange.Font.Underline = (WdUnderline)0;
docWholeRange.Text = docWholeRange.Text + docRange.Text;
}
}
wordDocument.Bookmarks.Add(bookmarkPlace, docWholeRange);
}
I tried using StringBuilder, however it is not possible to format each line separately and keep it formatted.
Then tried using Selection object in similar manner as shown in code and then tried to use Selection.TypeText. Instead of being entered at Bookmark place, it was actually starting from the beginning of word file. The size of the letter was way too small.
Managed to get all lines correctly to be written in Word without using StringBuilder.
However, trying to get all text lines between two bookmarks and all samples advising to use Bookmarks.get_Item and this does not exists in Visual Studio 2019 and C#.
Anyone has idea, how to store it into Range?
Tried following:
object start = bm.Range.End;
object end = ebm.Range.Start;
Microsoft.Office.Interop.Word.Range textRange = wordDocument.Range(ref start, ref end);
bm and ebm are two bookmarks.
I am trying to store all text line into range, then iterate line by line and change font size/bold in each text line.
Anyone has better idea how it can be done.
Regards,

How do I make Autofill for excel work properly?

Update: I have tried using other Excel.XlAutoFillType, sadly it did not work.
The types are (here)
ORIGINAL QUESTION:
I'm new to VSTO and now writing an VSTO add-in for Excel(2013 or higher version). The Autofill method is Range.AutoFill(Range, XlAutoFillType) from Microsoft.Office.Interop.Excel (See Documentation from MS).
I have a date (like 25.02.2020) and want the excel to autofill the rest of the column with the dates after it (ex. A1:25.02.2020; A2:26.02.2020; A3:27.02.2020; ... A6:01.03.2020; ...).
As I tried manually to do it in excel, it worked, as long as I selected two or more cells as examples.
Image see: https://i.imgur.com/L8Enqrr.png (As StackOverflow doesn't allow me to post photos)
However, when I tried to use the autofill method, it failed and only added the years. (B2 was provided as an example for excel)
image see: https://i.imgur.com/smWpo0Y.png
Here is my code:
// Datetime dates[] = new dates[3] {dt1, dt2, dt3}
// Int[] dateLength = new Int[3] {0, (int)Math.Ceiling(dates[1].Subtract(dates[0]).TotalDays), ((int)Math.Ceiling(dates[2].Subtract(dates[1]).TotalDays) + (int)Math.Ceiling(dates[1].Subtract(dates[0]).TotalDays))}
for (int i = 0, j = 0; i < dates.Length; i++, j++)
{
Excel.Worksheet activeWst = Globals.ThisAddIn.Application.ActiveSheet;
Excel.Range tRange = activeWst.Range[activeWst.Cells[dateLength[i] + 2 + j, 2], activeWst.Cells[dateLength[i] + 2 + j, 2]];
tRange.Value = dates[i].ToString("dd/MM/yyyy");
if (i < dates.Length - 1) {
tRange.AutoFill(activeWst.Range[activeWst.Cells[dateLength[i] + 2 + j, 2], activeWst.Cells[dateLength[i + 1] + j + 1, 2]]);
}
}
Thanks.
I have found the answer myself. As the date value in every cell is stored as String, the Autofill won't work.
tRange.Value = dates[i].ToString("dd/MM/yyyy"); //The problem
The only thing is to write the dates in the cells directly and change the entire column's number format to what you like.
//Fixed code
tRange.EntireColumn.NumberFormat = "dd-MM-yyyy";
tRange.Value = dates[i].Date;
And BTW, it works with the default XlAutoFillType(Excel.XlAutoFillType.xlFillDefault).
tRange.AutoFill(activeWst.Range[activeWst.Cells[dateLength[i] + 2 + j, 2], activeWst.Cells[dateLength[i + 1] + j + 1, 2]], Excel.XlAutoFillType.xlFillDefault);
I appreciate everyone's help. Thank you a lot.

C# datatable computing

I am computing in the large datatable. The table name is templetable.
I am trying to calculate the sum from the 4th column to the last column and save the results to another datatable. But I am getting errors as it says could not find the column "colPnow"
Any ideas?
DataView dv2 = new DataView(SP_dt);
for (int i = 0; i < LoadIDcount; i++)
{
string IDnow = LoadID[i, 0];
dv2.RowFilter = String.Format("Load_ID = '{0}'", IDnow);
DataTable temptable = dv2.ToTable();
for (int j = 0; j < 8760; j++)
{
string colPnow = SP_dt.Columns[j*2 + 4].ColumnName.ToString();
double ColP_sum= (double)temptable.Compute("Sum(colPnow)", String.Format("Load_ID = '{0}'", IDnow));
string colQnow = SP_dt.Columns[j*2 + 5].ColumnName.ToString();
double ColQ_sum = (double)temptable.Compute("Sum(colQnow)", String.Format("Load_ID = '{0}'", IDnow));
Load_dt.Rows[i][j * 2 + 2] = ColP_sum;
Load_dt.Rows[i][j * 2 + 3] = ColQ_sum;
}
}
You are not formatting your expression string correctly in the Compute method. Use another String.Format and it will work. Your Compute expression is currently literally equal to "Sum(colPnow)". You want the actual column name string that is stored in your colPnow variable.
Change this part of your code to this:
string colPnow = SP_dt.Columns[j*2 + 4].ColumnName.ToString();
double ColP_sum= (double)temptable.Compute(String.Format("Sum([{0}])", colPnow),
String.Format("Load_ID = '{0}'", IDnow));
The same should be done for your colQnow variable. I would also suggest you read how String.Format works so that you can grasp the string formatting concept.

Excel Open xml sdk - Copy formula between cells with range modification

I have a cell with formula (CellFormula). I don't know the formula content (Might be Sum, ifs or any other calculation).
The formula might include range.
When you drag the cell to other cells (manually at excel application itself) the formula range get updated.
I want the formula programatic copy to behave the same way.
If the formula contains range specifiers I want to update them to the current row.
Is there some built-in way to do so without regular expression manipulations?
I don't know if it's a good solution that cover all possibilities but...
//Formula update
if (cloneFromCell.CellFormula != null && (cloneFromCell.CellFormula.FormulaType == null || !cloneFromCell.CellFormula.FormulaType.HasValue || cloneFromCell.CellFormula.FormulaType.Value == CellFormulaValues.Normal))
{
uint cloneRowIndex = OXMLTools.GetRowIndex(cloneFromCell.CellReference);
uint offset = rowIndex - cloneRowIndex;
exCell.CellFormula.Text = OXMLTools.GetUpdatedFormulaToNewRow(cloneFromCell.CellFormula.Text, offset);
}
public static string GetUpdatedFormulaToNewRow(string formula, uint offset)
{
return Regex.Replace(formula, #"[A-Za-z]+\d+", delegate(Match match)
{
//Calculate the new row for this cell in the formula by the given offset
uint oldRow = GetRowIndex(match.Value);
string col = GetColumnName(match.Value);
uint newRow = oldRow + offset;
//Create the new reference for this cell
string newRef = col + newRow;
return newRef;
});
}

Convert Excel Cell Value From Text To Number Using C#

I am using Windows Application. In that Application i exported the DataGrid into Excel Successfully... Now the problem is , When i exported from Grid to the Excel Sheet, The cell values are having some green color mark on left top corner in the Excel Sheet... I thought that is type cast problem . How Shall i avoid that Problem.... and How to change the cell value from text to Number ...(i.e)Convert To Number....
Can Anyone tell me the solution of this problem?
My Code for Formatting That Excel Sheet For Some Range of Values,
wksheet.Range[GetRanges[0].ToString(), GetRanges[GetRanges.Count-2].ToString()].Merge();
wksheet.get_Range(GetRanges[0].ToString(), GetRanges[GetRanges.Count-].ToString()).Interior.Color = Color.FromArgb(192, 0, 0);
I haven't a Windows machine to test on at the moment, but perhaps you would want to try changing the cell format, e.g.:
my_range.NumberFormat = "0.0"; // change number of decimal places as needed
Here's a full example from Microsoft: How to automate Microsoft Excel from Microsoft Visual C#.NET.
The following routine will dynamically fill a spreadsheet from data (text and numbers) in a text file.
The kicker is using an object array to set the values.
StreamReader STRead;
String[] STCells;
object[] cellData;
int temp;
Excel.Range tempRange;
for (int i = 0; i < FileList.Length; i++)
{
STRead = FileList[i].OpenText();
int j = 0;
while (!STRead.EndOfStream)
{
STCells = STRead.ReadLine().Split(',');
cellData = new object[STCells.Length];
for (int k = 0; k < STCells.Length; k++)
{
if (Int32.TryParse(STCells[k], out temp))
cellData[k] = temp;
else
cellData[k] = STCells[k];
}
tempRange = sheetList[i].get_Range(ReturnCellID(j, 0),
ReturnCellID(j, STCells.Length - 1));
j++;
tempRange.Value2 = cellData;
}
STRead.Close();
}
I had this problem with a excel sheet containing both regular numbers and percent (a result of an export of strings from a Crystal Report).
To change all of them at once I made a loop somewhat like this:
//example range
Excel.Range rng = mWorkSheet.get_Range("A1", "H25");
foreach (Excel.Range range in rng)
{
if (range.Value != null)
{
int number;
bool isNumber = int.TryParse(range.Value.ToString().Trim(), out number);
if (isNumber)
{
range.NumberFormat = "#,##0";
range.Value = number;
}
else
{
//the percent values were decimals with commas in the string
string temp = range.Value.ToString();
temp = temp.Replace(",", ".");
range.Value = temp;
}
}
}
Result was that both the percentage strings and the numbers got converted into the correct Excel format.
When you assign the value to the cells, try to get all the values in an 2 dimensional array first and then assign the array to the Range. this way its going to be very fast and also i guess the values in the cell will be number. try it out ...hopefully it should work
Change the cell value from text to Number is easy with Excel Jet Cell .NET component.
Cell["A1"].Style.StringFormat = "##.#"; // or "0.0" same as in MS Excel

Categories

Resources