I am looking to accumulate the value of each cell and display this in a "total column" at the end of the grid in flex cell. Which is the best way of going about this?
I have following code so far which I don't think is correct!
int total = 0;
for (int B = 3; B < 27; B++)
{
total = total + int.Parse(this.grid2.Cell(0, B).ToString());
this.grid2.Cell(0, 27).Text = total.ToString();
}
Your code seems correct to me, but it can be improved:
int total = 0;
for (int B = 3; B < 27; B++)
{
total = total + Convert.ToInt32(this.grid2.Cell(0, B));
}
this.grid2.Cell(0, 27).Text = total.ToString();
Only put things that need to be repeated inside the for-loop. If it only needs to be done once, put it after (or before if possible) the loop.
Also, try to use more meaningfull names for your variables. I would change 'B' to either 'i' if you don't want to give it a long name, or to 'column', so you (and other developers, like us) know what it stands for.
BTW, the code calculates the sum for one row (the first one). If you want to do it for every row, then you will need a double for-loop:
for(int row = 0;row < numRows; row++){
int total = 0;
for (int column = 3; column < 27; column++)
{
total = total + Convert.ToInt32(this.grid2.Cell(row, column));
}
this.grid2.Cell(row, 27).Text = total.ToString();
}
Related
I have a datagridview column with values formed by multiple digits.
I'm tryng to obtain the sum of all cell value from this column but first I need to sum the digits in the single cell.
column
Example: every cell has "201" value. I need to obtain "3" as result and then do the sum of all the rows values. So if I have 3 row with 201, I need to obtain 3 for each and then 9 as the total.
How can do this?
This is my code but it seems to give wrong results.
int sum4 = 0;
for (int p = 0; p < dataGridView1.Rows.Count; ++p)
{
sum4 += Convert.ToInt32(dataGridView1.Rows[p].Cells[4].Value);
}
int sum5 = 0;
while (sum4 != 0)
{
sum5 += sum4 % 10;
sum4 /= 10;
}
label22.Text = sum5.ToString();
Now with 3 rows it's giving me 9 as result, with 4 row give me 12 but when I have 5 row it's giving me 6!
EDIT
The solution provided works but I missed a step.
In my datagridview I need first to multiply the "Ripetizioni" value for the "Serie" value and then multiply this for the sum of seconds of the "Time under Tension" column. A the end the sum of all rows values.
So, for a single row I need the multiply of 11 x 3 (first wor example) then the sum of 201 with 3 as result and the multiply of 11x3= 33 x (sum of 201 result). At the end the sum of all rows
How can I achieve this?
Try this. In your solution you are changing value of sum4 every time. This is wrong.
int finalSum = 0;
for (int p = 0; p < dataGridView1.Rows.Count; ++p)
{
finalSum += getCellDigitSum(Convert.ToInt32(dataGridView1.Rows[p].Cells[4].Value));
}
label22.Text = finalSum.ToString();
int getCellDigitSum(int cellValue)
{
int l = cellValue;
int result = 0;
while (l > 0)
{
result += (l % 10);
l = l / 10;
}
return result;
}
Assignment for game design using the Microsoft C# tutorial as a basis
Display to console
the value held by number1 in a grid
with number2 amount of rows
and number3 amount of columns.
Something like "If num1 is 8 * row = 4 and column = 5"
I'm sorry I'm just beginning to learn this.
for (int row = number2; row < number1; row++)
{
for (int column = number3; column <= number1; column++)
{
Console.WriteLine($"{row}{column}");
}
}
Given your comment description
What I'm basically trying to do is to print a grid of numbers using
user input. Num1 is the number that'll be printed, num2 is how many
rows they'll be, and num3 is how many columns they'll be. I've tried
switching up the Var placements but it hasn't given me the result I
prefer.
Potentially, this might be what you are looking for
var charToPrint = 'x';
var rows = 5;
var columns = 4;
for (var i = 0; i < rows; i++)
{
for (var j = 0; j < columns; j++)
Console.Write(charToPrint); // writes character at a time for each column
Console.WriteLine(); // write a new line for end of row
}
Output
xxxx
xxxx
xxxx
xxxx
xxxx
Full Demo Here
Another way might be using Enumerable.Range, Select, string.Join and the string constructor
var result = Enumerable
.Range(1, rows)
.Select(x => new string(charToPrint,columns));
Console.WriteLine(string.Join(Environment.NewLine,result));
To do the input validation you could do something like this
var input = string.Empty;
var rows = 5;
var columns = 4;
Console.WriteLine("Enter character to print");
while ((input = Console.ReadLine()).Length != 1)
Console.WriteLine("you had one job! Enter character to print");
var charToPrint = input[0];
Console.WriteLine("Enter the number of rows");
while (!int.TryParse(Console.ReadLine(),out rows))
Console.WriteLine("you had one job! Enter the number of rows");
Console.WriteLine("Enter the number of columns");
while (!int.TryParse(Console.ReadLine(),out columns))
Console.WriteLine("you had one job! Enter the number of columns");
Example output
Enter character to print
23423
you had one job! Enter character to print
d
Enter the number of rows
d
you had one job! Enter the number of rows
5
Enter the number of columns
4
dddd
dddd
dddd
dddd
dddd
It was this..
for(int row = 0; row < number2; row++)
{
for(int column = 0; column < number3; column++)
{
Console.Write(number1);// once it prints number1
}
Console.WriteLine();// it goes to next line
}
How can I get the sum of values from the column "Quantity" that match a selected value in the column "Le Nom". For example :
Le Nom Quantity
HEA200 200
HEB300 150
IPE450 700
HEA200 300
Let's say that the first row is selected, I want to sum the first one (200) and the fourth one (300) since they share the same value (HEA200).
Here is my code to get the sum of all values, but I can't achieve my goal.
int sum = 0;
string NameProfil =
gridView2.GetRowCellValue(gridView2.FocusedRowHandle, "Le Nom").ToString();
for (int i = 0; i < gridView2.RowCount; i++)
{
sum += int.Parse(Convert.ToString(gridView2.GetRowCellValue(i, "Quantité")));
}
MessageBox.Show(sum.ToString() + " "+ NameProfil);
int sum = 0;
string NameProfil = gridView2.GetRowCellValue(gridView2.FocusedRowHandle, "Le Nom").ToString();
for (int i = 0; i < gridView2.RowCount; i++)
{
if(gridView2.GetRowCellValue(i, "Le Nom").ToString() == NameProfil)
{
sum += int.Parse(gridView2.GetRowCellValue(i, "Quantité").ToString());
}
}
MessageBox.Show(sum + " "+ NameProfil);
should do the trick.
Also, .ToString() will be implicitly called on sum when trying to concatenate it with strings, so - while not incorrect - it is not needed.
I have this for loop. TicketList starts with 109 tickets. nColumns = 100. I calculate the number of rows I will need depending on the number of tickets. So in this case I need 2 rows. Row one will be full and row two will only have 9 entries. I have the loop below. It only runs one time for the NumOfRows and fills the first 100 and never loops.
What am I missing?
for (int j = 0; j < NumOfRows; j++)
{
for (int i = 0; i < nColumns; i++)
{
if (TicketList.Count() > 0)
{
t = rand.Next(0, TicketList.Count() - 1);
numbers[i, j] = TicketList[t];
TicketList.Remove(TicketList[t]);
}
}
}
Try changing your code to use a more LINQ-like, functional approach. If might make the logic easier. Something like this:
TicketList
.OrderBy(x => rand.Next())
.Select((ticket, n) => new
{
ticket,
j = n / NumOfRows,
i = n % NumOfRows
})
.ToList()
.ForEach(x =>
{
numbers[x.i, x.j] = x.ticket;
});
You may need to flip around x.i & x.j or use nColumns instead of NumOfRows - I wasn't sure what your logic was looking for - but this code might work better.
Other than a few poor choices, your loops appear to be fine. I would venture that NumOfRows is not being calculated correctly.
The expression NumOfRows = (TotalTickets + (Columns - 1)) / Columns; should calculate the correct number of rows.
Also, you should use the property version of Count rather than the Linq extension method and use IList<T>.RemoveAt() or List<T>.RemoveAt rather than Remove(TicketList[T]).
Using Remove() requires that the list be enumerated to locate the element to remove, which may not be the same index that you are targeting. Not to mention that you will scan 50% (on average) of the list for each Remove call, when you already know the correct index to remove.
The functional approach listed earlier seems like overkill.
I've attempted to replicate your issue, assuming certain facts about the various variables in use. The loop repeats the expected number of times.
static void TestMe ()
{
List<object> TicketList = new List<object>();
for (int index = 0; index < 109; index++)
TicketList.Add(new object());
var rand = new Random();
int nColumns = 100;
int NumOfRows = (TicketList.Count + (nColumns - 1)) / nColumns;
object[,] numbers;
int t;
numbers = new object[nColumns, NumOfRows];
for (int j = 0; j < NumOfRows; j++)
{
Console.WriteLine("OuterLoop");
for (int i = 0; i < nColumns; i++)
{
if (TicketList.Count > 0)
{
t = rand.Next(0, TicketList.Count - 1);
numbers[i, j] = TicketList[t];
TicketList.RemoveAt(t);
}
}
}
}
The problem that you are seeing must be the result of something that you have not included in your sample.
I am tried to create a data list display all cuisine in alphabetical order in column however i couldn't find the way to do it, can any one help.
using data list or repeater in asp.net only allow you to display in horizontal or vertical alphabetical order for example
Afghan Asian Burmese Cambodian
Chinese Croatian European French
Greek Indian International Italian
What I want to have is
Afghan Chinese Greek
Asian Croatian Indian
Burmese European International
Cambodian French Italian
Thank you
nickf's answer helped me come to the following method that will transform a list as needed:
public static List<T> ReorderListIntoColumns<T>(List<T> list, int totalColumns)
{
List<T> reordered = new List<T>();
int itemsPerColumn = (int) list.Count / totalColumns;
for (int i = 0; i < itemsPerColumn; i++)
{
for (int j = 0; j < totalColumns; j++)
{
reordered.Add(list[(j * itemsPerColumn) + i]);
}
}
return reordered;
}
This topic seems to get a lot of views even though there was no accepted answer. Hopefully this will help someone else out that needs to reorder a list in this way!
What I'd do is get your list in alphabetical order, and then rearrange such that when you use the datalist/repeater default ordering, it's in your desired format.
In bizarre pseudo-code.
/*
your input is A,B,C,D,E,F,G,H,I,J,K,L
given this order, it returns:
A, B, C
D, E, F
G, H, I
J, K, L
but you want
A, E, I
B, F, J
C, G, K
D, H, L
So you need to change your input to this:
A,E,I,B,F,J,C,G,K,D,H,L
*/
let numColumns = 3;
let numItems = 12;
let itemsPerColumn = numItems / numColumns;
loop i from 0 to itemsPerColumn - 1
loop j from 0 to numColumns - 1
newOrdering.push(oldOrdering[i * numColumns + j])
There might be some nifty .NET feature to change the ordering style, but this is just one old-school method.
PS: This is working on the best case scenario, which is that the number of items is evenly divisible by the number of columns. You'll have to adjust somewhat for different values.
I recently accomplished this using a PlaceHolder and a custom table:
<asp:PlaceHolder ID="locationTablePlaceHolder" runat="server"/>
Then in the backing code:
DataView view = locations.Tables[0].DefaultView;
view.Sort = "locationName";
Table table = new Table();
locationTablePlaceHolder.Controls.Clear();
locationTablePlaceHolder.Controls.Add(table);
// enumerator to loop through all items in the DataView
IEnumerator enumerator = view.GetEnumerator();
enumerator.Reset();
// first create all the row objects since we want to populate
// column by column.
int rowCount = 5;
int colCount = 5;
for (int i = 0; i < rowCount; i++)
{
TableRow row = new TableRow();
table.Rows.Add(row);
}
// then loop through each column taking items from the enumerator
// to populate the table
for (int j = 0; j < colCount; j++)
{
for (int i = 0; i < rowCount; i++)
{
TableCell cell = new TableCell();
if (enumerator.MoveNext())
{
Label label = new Label();
label.Text = (String)((DataRowView)enumerator.Current).Row["locationName"];
cell.Controls.Add(label);
table.Rows[i].Cells.Add(cell);
}
}
}