Write to cell in excel using c# error - c#

I am getting error "Not enough storage is available to complete this operation" during writing to cell in excel using c#.
I know that excel sheet not allows us to write more than 32,767 characters per cell.
I am writing 32,000 characters per cell.
It allows me to write first 3 cell in 1st columns but for the 4th, it throws the above error. what is the reason of that? any idea?
TOTAL LENGTH OF xml_txt_length is 2,65,000.
I have marked code by ******* in comments below where i am getting error.
my code is below:
if (xml_txt_length > 32000) // checking length of text is more than 32,000. if yes than need to split it to write in cell
{
int counter = 0; // used to multiply to 32,000
while (true)
{
if (counter == 0)
{
cell_string = xmlText.Substring(0, 32000);
xml_string += cell_string;
// writing to cell for column1
oSheet3.Cells[counter + 1, 1] = cell_string;
}
else
{
// if taken 32,000 characters exceeds the end length of string then go into this condition and take actual final position.
if ((32000 * counter) + 32000 >= xml_txt_length)
{
// below substring taking start position and up to end character of string instead of putting directly last 32,000th character position
cell_string = xmlText.Substring(32000 * counter, Convert.ToInt32(xml_txt_length - (32000 * counter)));
xml_string += cell_string;
//writing to cell for column 1
oSheet3.Cells[counter + 1, 1] = cell_string;
break;
}
else
{
// taking the start and upto 32,000 characters from string
cell_string = xmlText.Substring(32000 * counter, 32000);
xml_string += cell_string;
// writing to cell for column 1
// ********************************************************
// **** HERE I AM GETTING ERROR FOR CELL 4 IN COLUMN 1 ****
oSheet3.Cells[counter + 1, 1] = cell_string;
cell_string = string.Empty;
}
}
if (counter >= Math.Floor(xml_txt_length / 32000))
break;
counter++;
}
}
else
oSheet3.Cells[1, 1] = xmlText;

Related

Unicode have different width when printing

I am developing a chess engine in C#/Unity and want to print the board on a nice format. Preferably I want to print with some Unicode pieces but they end up making the board uneven, see image below:
The same seems to go for normal numbers since each row starts slightly off one another, row 1 starts more left than the others for example.
Why does my Debug.Log/prints end up like this, and how can I print them so that each character takes up the same amount of space?
EDIT:
Here is the code I use to Debug.Log the board if that helps:
public static void PrintBitboard(ulong bitboard)
{
string zero = " 0 ";
string one = " 1 ";
string printString = "";
// Loop through all squares and print a 1 if piece and 0 if not a piece on the square
for (int row = 0; row < 8; row++)
{
// Add numbering on the left side
printString += (8 - row) + " ";
for (int col = 0; col < 8; col++)
{
int currentSquare = row * 8 + col;
printString += BitOperations.GetBit(bitboard, currentSquare) != 0 ? one : zero;
}
// Change to new row
printString += "\n";
}
// Print bottom letters
printString += "\n" + " a b c d e f g h";
// Send message to the console
Debug.Log(printString);
}
What you are looking for is not "unicode" but monospace
-> As GiacomoCatenazzi already said, the only thing responsible for that is the font you are using
As a "quick and dirty" fix / alternative you could try and simply use tabs (\t) instead of spaces like (in general for larger string based concatenations I would recommend to use a StringBuider)
public static void PrintBitboard(ulong bitboard)
{
const string zero = "0\t";
const string one = "1\t";
var stringBuilder = new StringBuilder();
// Loop through all squares and print a 1 if piece and 0 if not a piece on the square
for (int row = 0; row < 8; row++)
{
// Add numbering on the left side
stringBuilder.Append((8 - row)).Append('\t');
for (int col = 0; col < 8; col++)
{
int currentSquare = row * 8 + col;
stringBuilder.Append(BitOperations.GetBit(bitboard, currentSquare) != 0 ? one : zero);
}
// Change to new row
stringBuilder.Append('\n');
}
// Print bottom letters
stringBuilder.Append("\n \ta\tb\tc\td\te\tf\tg\th");
// Send message to the console
Debug.Log(stringBuilder.ToString());
}
See .Net Fiddle which in the Unity console would look like
(in both I had to tricks a bit since I don't know what BitOperations implementation you are using)

How to skip empty cells while reading data from Excel using OpenXML?

I am trying to read data from Excel and store it into a DataTable using OpenXML. I want data in my DataTable as it is in Excel sheet but when there is a empty cell in Excel, it was not looking as expected.
Because code row.Descendants<Cell>().ElementAt(i) skips empty cells while reading data and in DataTable Rows and Columns are stored incorrectly. I resolved this issue using below code but when my excel has more than 26 columns, it is not working as expected and again data are stored in DataTable incorrectly.
(i.e., While reading data from AA, AB, AC columns)
Can someone help me to rewrite this code to handle this issue when there is more than 26 columns.
private static int CellReferenceToIndex(Cell cell)
{
int index = 0;
string reference = cell.CellReference.ToString().ToUpper();
foreach (char ch in reference)
{
if (Char.IsLetter(ch))
{
int value = (int)ch - (int)'A';
index = (index == 0) ? value : ((index + 1) * 26) + value;
}
else
{
return index;
}
}
return index;
}
You can use example below (taken from here and improved by few validations):
public static int GetColumnIndex(this Cell cell)
{
string columnName = string.Empty;
if (cell != null)
{
string cellReference = cell.CellReference?.ToString();
if (!string.IsNullOrEmpty(cellReference))
// Using `Regex` to "pull out" only letters from cell reference
// (leave only "AB" column name from "AB123" cell reference)
columnName = Regex.Match(cellReference, #"[A-Z]{1,3}").Value;
}
// Column name validations (not null, not empty and contains only UPPERCASED letters)
// *uppercasing may be done manually with columnName.ToUpper()
if (string.IsNullOrEmpty(columnName))
throw new ArgumentException("Column name was not defined.", nameof(columnName));
else if (!Regex.IsMatch(columnName, #"^[A-Z]{1,3}$"))
throw new ArgumentException("Column name is not valid.", nameof(columnName));
int index = 0;
int pow = 1;
// A - 1 iteration, AA - 2 iterations, AAA - 3 iterations.
// On each iteration pow value multiplies by 26
// Letter number (in alphabet) + 1 multiplied by pow value
for (int i = columnName.Length - 1; i >= 0; i--)
{
index += (columnName[i] - 'A' + 1) * pow;
pow *= 26;
}
// Index couldn't be greater than 16384
if (index >= 16384)
throw new IndexOutOfRangeException("Index of provided column name (" + index + ") exceeds max range (16384).");
return index;
}
All exception throws you can replace with return -1 and some kind of Log("...") if you have logging. Otherwise you may not be sure what's problem happened and why was returned -1.
Usage is obvious:
var cells = row.Descendants<Cell>();
foreach (Cell cell in cells)
{
int columnIndex = cell.GetColumnIndex();
// Do what you want with that
}
EDIT.
I'm not sure what you're trying to achieve. And what you mean here:
Because code row.Descendants<Cell>().ElementAt(i) skips empty cells...
I didn't see that. Look at example below:
Random ElementAt in range between 0 and Descendants<Cell>().Count() works too and shows both empty and non-empty cells:

Specific Odd Numbered Inverted Triangle Question in C#

I Would really appreciate some help on this question I will sum it up myself but also include the actual instruction and my code so far.
Write a console C# program to do the following:
Ask user max number of characters. This should be an odd number if user enters even number add 1 to it to convert it to odd number.
Ask user the character to print
Your program should then output two inverted vertical triangles of base equal to number entered in #1 and made of characters in #2
Number of characters in one line of the triangle should differ by 2 from its next line such that the top of the triangle has only 1 character.
The top of the triangle (single character) should be centralized appropriately
Make sure your code follows these guidelines
-The output string should be returned as a single string variable from a class
-Class should have a public function that will returns the string and takes the input for #1 and #2 as argument
-Code should be well commented and indented
-Check for all invalid input values (e.g. for #1 no character should be accepted). Suitable message should be displayed to user for incorrect input
-All 5 requirements should be met
-Code should compile and run without any error or warnings
Example:
If user enters 9 for #1 and enters the character ‘*’ for #2 the program should print the following:
*
***
*****
*******
*********
*********
*******
*****
***
*
Thus far I can get the code to print out the correct number of characters, but not to align correctly into this shape.
I will attach my code at the bottom of this post. Whoever may respond, can you explain exactly how the for loop is working on order to achieve this? I know this is not an extremely difficult question, but C# is a new language to me, the course is entirely online, and I feel lost in such conceptual thinking. Thank you so much to whoever responds.
public class Class1
{
public void Main(string[] args)
{
int n;
char ch;
try
{
Console.Write("Enter the Max Number of Characters ::");
n = int.Parse(Console.ReadLine());
if (n % 2 == 0)
n++;
Console.Write("Enter Character Which You Want to Print ::");//output message for display
ch = char.Parse(Console.ReadLine());//value to get from user
Console.WriteLine(PatternPrint(n, ch));
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
public string PatternPrint(int n, char ch)
{
int i, j, k, l;//variable to declare
string str = "";//string to display
for (i = 1; i <= n; i++)
{
for (j = 1; j <= n - i; j++)
{
str = str + " ";
}
for (k = 1; k <= i; k++)
{
str = str + ch;
}
for (l = i -1; l >= 1; l--)
{
str = str + ch;
}
str = str + "\n";
}
return str;//return string
}
}
}
You have a problem with your logic, as it prints only in one direction. Whereas, as per your requirement you need reverse direction pattern as well.
Your code output is :
*
***
*****
*******
*********
***********
*************
***************
*****************
Please try below code as it prints in both direction.
using System;
public class Test
{
public static void Main()
{
Console.Write("Enter the Max Number of Characters ::");
int totalChar = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter Character Which You Want to Print ::")
char character = char.Parse(Console.ReadLine());
totalChar = (totalChar % 2 == 0) ? totalChar += 1 : totalChar;
int mainIndex, spaceIndex, charIndex;
for(mainIndex = 1; mainIndex <= totalChar; mainIndex += 2)
{
for(spaceIndex = totalChar; spaceIndex >= mainIndex; spaceIndex -= 2)
Console.Write(" ");
for(charIndex = 1; charIndex <= mainIndex; charIndex++)
Console.Write(character);
Console.WriteLine();
}
for(mainIndex = totalChar; mainIndex >= 1; mainIndex -= 2)
{
for(spaceIndex = mainIndex; spaceIndex <= totalChar; spaceIndex += 2)
Console.Write(" ");
for(charIndex = 1; charIndex <= mainIndex; charIndex++)
Console.Write(character);
Console.WriteLine();
}
}
}
Sample Input : 9 & *
Sample Output:
*
***
*****
*******
*********
*********
*******
*****
***
*
This code works for me:
public string PatternPrint(int n, char ch) =>
String.Join(
Environment.NewLine,
Enumerable
.Range(1 - n / 2, n - 1)
.Select(x => Math.Abs(x))
.Select(i => "".PadLeft(i) + "".PadLeft(n - 2 * i - 1, ch)));
Given 5 and # I get:
#
###
#####
###
#
Here's brief explanation from me -
Observing example -
Input => Character to use '*', Maximum it can appear is 9 times (triangle's base).
Each line in triangle can be formatted in two ways -
White spaces, then characters.
White spaces, then characters, then again white spaces.
Observing your code -
You seem to using the first approach.
Your 1st loop add white spaces.
You may find this surprising, but your 2nd and 3rd do the same thing, they add characters, except 3rd loop has 1 less character.
What we need based on the example -
If max character usage per line is n, we need to have n+1 lines. (One more because lower triangle does not share base)
A triangle completes in (n+1)/2 lines.
To complete upper triangle, each line needs, each line needs
White spaces starting from (n-1)/2, decreasing by 1.
Characters starting from 1, increasing by 2.
To complete lower triangle, each line needs
White spaces starting from 0, increasing by 1.
Characters starting from n, decreasing by 2.
I would encourage you try yourself, but after you are done, here's the reference code -
public static string PatternPrint(int n, char ch)
{
StringBuilder sb = new StringBuilder();
int spaces, characters;
// Upper triangle
spaces = (n - 1) / 2;
characters = 1;
for (int i = 0; i < (n+1)/2; i++)
{
Enumerable.Repeat(' ', spaces).ToList().ForEach(space => sb.Append(space));
Enumerable.Repeat(ch, characters).ToList().ForEach(character => sb.Append(character));
sb.Append('\n');
spaces -= 1;
characters += 2;
}
// Lower triangle
spaces = 0;
characters = n;
for (int i = 0; i < (n+1)/2; i++)
{
Enumerable.Repeat(' ', spaces).ToList().ForEach(space => sb.Append(space));
Enumerable.Repeat(ch, characters).ToList().ForEach(character => sb.Append(character));
sb.Append('\n');
spaces += 1;
characters -= 2;
}
return sb.ToString();
}
Above code related notes -
Use StringBuilder to manipulate your string. It is more efficient, and easy I would say. Available in namespace System.Text
C# offers Linq library in namespace System.Linq. Enumerable used in code is part of it. It offers many more things, and extension methods. Really cool.
There's always room for improvement. My solution works based on assumptions. It silently fails when those assumptions are broken. Hint: evens

Replace a character in specific position if line starts with condition C#

I am trying to modify a txt file, I need to change the 45 character with a P if the line starts with 8
for (int i = 0; i < textBox.Lines.Length; i++)//Loops through each line of text in RichTextBox
{
string text = textBox.Lines[i];
if ((text.Contains("8") == true)) //Checks if the line contains 8.
{
char replace = 'P';
int startindex = textBox.GetFirstCharIndexFromLine(i);
int endindex = text.Length;
textBox.Select(startindex, endindex);//Selects the text.
richTextBox1.Text = textBox.Text.Substring(0, textBox.SelectionStart) + (0, textBox.Lines) + replace + textBox.Text.Substring(textBox.SelectionStart + 45);
}}
To accomplish your goal the code could be changed in this way
//Loops through each line of text in RichTextBox
for (int i = 0; i < textBox.Lines.Length; i++)
{
string text = textBox.Lines[i];
//Checks if the line starts with "8".
if (text.StartsWith("8"))
{
// Find the 45th position from the start of the line
int startindex = textBox.GetFirstCharIndexFromLine(i) + 45;
// Starting from the found index select 1 char
textBox.Select(startindex, 1);
// Replace the selected char with the "P"
textBox.SelectedText = "P";
}
}
The key points changed are the way to select into a textbox. The Select method requires a starting index and the number of character to select, finally, once you have a SelectedText, (a read/write property) you can simply replace the current SelectedText with your own text. Lot easier than your current (and wrong) calculation.

WinRT - How to get line and column at cursor from a TextBox?

How do I get line and column at cursor from a text box in my Windows 8 Metro App? There is no GetFirstCharIndexFromLine method like there was in WinForms.
Here is one way to accomplish this:
// Returns a one-based line number and column of the selection start
private static Tuple<int, int> GetPosition(TextBox text)
{
// Selection start always reports the position as though newlines are one character
string contents = text.Text.Replace(Environment.NewLine, "\n");
int i, pos = 0, line = 1;
// Loop through all the lines up to the selection start
while ((i = contents.IndexOf('\n', pos, text.SelectionStart - pos)) != -1)
{
pos = i + 1;
line++;
}
// Column is the remaining characters
int column = text.SelectionStart - pos + 1;
return Tuple.Create(line, column);
}
This will get the line and column numbers.

Categories