I have a C# web form where a user inputs data about an excel file into a number of text boxes, including:
TXT_FirstDataRow - integer field which represents the first row that contains data
TXT_LastDataColumn - string field which represents the last column that contains data
TXT_Range - string field which contains the calculated data range using the above two fields
TXT_ColumnCount - The number of columns in the calculated range
I am currently using jQuery to automatically calculate the data range using the code below which works perfectly:
$('#TXT_FirstDataRow,#TXT_LastDataColumn').keyup(function () {
var row = $('#TXT_FirstDataRow').val();
var column = $('#TXT_LastDataColumn').val();
var range = 'A' + row + ':' + column; //All ranges start at column A
$('#TXT_Range').val(range);
});
I would now like to automatically populate the TXT_ColumnCount with the count of the columns. For example:
Range |Column Count
------+------------
A1:C |3
A7:BX |76
I imagine that this should be made easier as the ranges will always be starting from column A, so the column count should just be the equivalent column number of TXT_LastDataColumn, but I am afraid even this is beyond my slightly limited jQuery knowledge.
Any help would be greatly appreciated.
Thanks
I found an answer on SO that helped me, link below:
Convert excel column alphabet (e.g. AA) to number (e.g., 25)
function letterToNumbers(string) {
string = string.toUpperCase();
var letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', sum = 0, i;
for (i = 0; i < string.length; i++) {
sum += Math.pow(letters.length, i) * (letters.indexOf(string.substr(((i + 1) * -1), 1)) + 1);
}
return sum;
}
Related
In Our assignment we were given a task to create a new spreadsheet program with a 26 x 26 grid of textboxes without importing anything and make use of array (in my case I Used array of objects).
I created a 2 d array of objects containing size of grid (27x27). the reason of it being 27 instead of 26 is because the first row and column is to show the ABCDE etc and 12345 etc of the rows and columns.
now the rows indexation I had no problem because it is numeric. however, the letters I solved by creating a string array with alphabet from a to z and entering them through a for loop and it worked.
Now the next step is to be able to link the cells, however, I am a bit stumped, because people told me I have to use Ascii or smthin.
Can anyone help me plz on how to achieve the cell links?
I have been able to past the name of each cell using this code but I fear I just filled the .Text of the cells not the cells name per se:
for (int x = 1; x < TwoDArrayCells.GetLength(0); x++) //nested loop to create the grid of textboxes.
{
for (int y = 1; y < TwoDArrayCells.GetLength(1); y++)
{
Cells CellFields = new Cells(Name = $"{AlphabetRow[x]}{y}", x, y + 3); // called a new cell named CellFields.
CellFields.Text = Name;//Change to location if you wise to take
this.Controls.Add(CellFields);
}
}
The result I would like is to be able to after this be able to link cells. meaning if I insert in a text box A1 + A2 it knows that a1 is the first box in the first row of first column and the a2 is the box in the second row of the first column.
Assuming that Columns can be A-Z only (Capitals), You can extract the column index and row index as follows:
Given a cell, string cell = "A2";
- the column index: int column = cell[0] - 'A' + 1;
- the row index: int row = Convert.ToInt32(cell.Substring(1));
Explanation: for the column, take the first letter, subtract it from 'A' (the subtraction will be performed on the assci codes of the characters) and add 1 since your actual cells are stored starting from index 1. for the row, just parse the rest of the string to int.
I've been working in a c# project and what I'm trying to accomplish is counting the visible rows of a filtered range in C#.
First, I create a range that I'm going to filter.
Range usedRange = sheet.Range[sheet.Cells[7, 1], sheet.UsedRange.SpecialCells(XlCellType.xlCellTypeLastCell)];
Then, I apply 2 filters:
usedRange.AutoFilter(20, "<>RAW", XlAutoFilterOperator.xlFilterValues, "<>AV", true);
usedRange.AutoFilter(2, "ARG", XlAutoFilterOperator.xlFilterValues, Type.Missing, true);
And last, I create another range, using the "XlCellType.xlCellTypeVisible" and try to count the rows, but the count returns 1
argFiltered = usedRange.SpecialCells(XlCellType.xlCellTypeVisible);
Console.WriteLine("Number of rows: "+ argFiltered.Rows.Count) // the count returns 1.
If I loop through the Range I Can get the count. But with a big amount of data this can slow the process a lot:
//this is not effective
foreach (Range area in argFiltered.Areas) {
foreach (Range areaRow in area) {
count++;
}
}
My question is: is there any way to get the number of the visible filtered rows "directly"?
Thank you all!
Note:
If I select the range, it selects the exact number of rows that should be displayed in the count!.
argFiltered.Select();
Not ideal but this will be somewhat better:
foreach (Range area in argFiltered.Areas) {
count += area.Rows.Count;
}
Can you afford to put a formula in some unused cell that counts the rows? If you use the Subtotal function with code 3 it won't count the rows hidden by a filter. Put a formula in a cell and read its value, e.g.
sheet.Cells[1, 255].Formula = "=subtotal(3, A1:A16383)"; //Count all rows that have a non-blank column A and aren't hidden
var count = sheet.Cells[1, 255].Value;
sheet.Cells[1, 255].ClearContents();
I have a dynamically created gridview that displays different pieces and their quantity. I want to get the total of these rows to display the total in the units column. So for example the value in the Unit column on the first row should be 190 (12 + 7 + 136 + 35)
The problem is the number of pieces can be different for each user. The example in the image has 13 pieces, but a different user might only have 5.
The units column will always be in the 9th position. So is there a way to check the value of each column after the unit column, till it reaches the end and then add those values together?
EDIT
main.Columns.Add("Units", typeof(int)).SetOrdinal(8);
foreach (DataRow row in main.Rows)
{
int total = 0;
for (int i = 9; i < main.Columns.Count - 1; i++)
{
total += row[i];
}
row["Units"] = total;
}
This program displays database information in a Data Grid View. I need to add all the numbers in column 1, add all the numbers in column 3, and multiply the two sums together.
This code only multiplies column 1 and column 3 from the last row. Any suggestions?
This is my first time connecting to a database, so I apologize if this seems like a dumb question
foreach (DataRow currentRow in itemDS.Tables[0].Rows)
{
// add to data grid view
invoiceDataGridView.Rows.Add(currentRow[1].ToString(), currentRow[2].ToString(), currentRow[3].ToString());
var itemQuant = Convert.ToDecimal(currentRow[1]);
var priceEach = Convert.ToDecimal(currentRow[3]);
decimal subTotal = itemQuant * priceEach;
subTotalOutput.Text = subTotal.ToString();
}
Do you mean you're not sure how to keep a running total in the looping construction? If so:
decimal total = 0; //declare outside the foreach
foreach (DataRow currentRow in itemDS.Tables[0].Rows)
{
// add to data grid view
invoiceDataGridView.Rows.Add(currentRow[1].ToString(), currentRow[2].ToString(), currentRow[3].ToString());
var itemQuant = Convert.ToDecimal(currentRow[1]);
var priceEach = Convert.ToDecimal(currentRow[3]);
decimal subTotal = itemQuant * priceEach;
total += subTotal;
}
//do something with total here, after for each finishes
you can use linq for taking sum of a column.
var sum = itemDS.Tables[0].AsEnumerable().Sum(dr => dr.Field<int>("value"));
"value" will be the column name of the datatable inside the itemDS. you have to specify your column name here.
Take the sum of next column like the above statement. add multiply it..
Hope this helps.. :)
I have a collection of strings that the user can add to or subtract from. I need a way to print the strings out in columns so that the 1st letter of each string aligned. However I the number of columns must be changeable during run time. Although the default is 4 columns the use can opt for any number from 1 to 6. I have no idea how to format an unknown quantity of string into an unknown number of columns.
Example Input:
it we so be a i o u t y z c yo bo go an
Example output of four columns
"Words" with 2 letters:
it so be we
yo bo go an
"Words" with 1 letter:
a i o u
t y z c
Note: not worried about parsing of the words I already have that in my code which I can add if helpful.
If you are trying to create fixed width columns, you can use string.PadLeft(paddingChar, width) and string.PadRight(paddingChar, width) when you are creating your rows.
http://msdn.microsoft.com/en-us/library/system.string.padleft.aspx
You can loop through your words and call .PadXXXX(width) on each word. It will automatically pad your words with the correct number of spaces to make your string the width you supplied.
You can divide the total line width by the number of columns and pad each string to that length. You may also want to trim extra long strings. Here's an example that pads strings that are shorter than the column width and trims strings that are longer. You may want to tweak the behavior for longer strings:
int Columns = 4;
int LineLength = 80;
public void WriteGroup(String[] group)
{
// determine the column width given the number of columns and the line width
int columnWidth = LineLength / Columns;
for (int i = 0; i < group.Length; i++)
{
if (i > 0 && i % Columns == 0)
{ // Finished a complete line; write a new-line to start on the next one
Console.WriteLine();
}
if (group[i].Length > columnWidth)
{ // This word is too long; truncate it to the column width
Console.WriteLine(group[i].Substring(0, columnWidth));
}
else
{ // Write out the word with spaces padding it to fill the column width
Console.Write(group[i].PadRight(columnWidth));
}
}
}
If you call the above method with this sample code:
var groupOfWords = new String[] { "alphabet", "alegator", "ant",
"ardvark", "ark", "all", "amp", "ally", "alley" };
WriteGroup(groupOfWords);
Then you should get output that looks like this:
alphabet alegator ant ardvark
ark all amp ally
alley