how to format in RTF using c#? - c#

I have below text in richTextBox control.
i want to format text like below text

The RTF box can help you here, the only help using RTF will be using a table as Kosala mentioned.
You may use string operations for that:
int equalPos = 20;
for (int l = 0; l < rtfBox.Lines.Length; l++) {
int i = rtfBox.lines[i].IndexOf('=');
int n = equalPos - i;
if ((i >= 0) && (n > 0)) {
rtfBox.lines[i] = rtfBox.lines[i].Insert(i, new string(' ', n));
}
}
Wrote this from head, so please check for errors.
EDIT:
Ok, here's another one:
for (int l = 0; l < rtfBox.Lines.Length; l++) {
int i = rtfBox.lines[i].IndexOf('=');
if (i >= 0) {
rtfBox.lines[i] = rtfBox.lines[i].Insert(i, "\t");
}
}
rtfBox.SelectAll();
rtfBox.SelectionTabs = new int[] { 100 }; // Find a value big enough!

This is what I would do.(These are manual steps.. :)
1).Open MSWord.
2).Create a table; 2 columns and 5 rows (this is for your text)
3). put the text that you wanted to format in to correct cells of the table
4). Save Word Doc as a rtf file.
5). Open rtf file in notepad(notepad++ is better)
There it is.. Now you can find how it is formatted. Now it should not be hard for you to do it in C#. Good luck.

Related

C# string.split is splitting letter by letter when pulled from IBM Emulator

I work in an IBM emulator environment. I'm trying to grab a row of text and split by spaces to return each word in the row. However, when printed to the console it's showing only first letters. This code has worked in the past when utilized on raw text or api results. The same code when implemented on an IBM Emulator does not however.
For example if the row from the emulator is HEALTHSELECT OF TEXAS , the code below would do the first and second console print correctly. With the double for-loop printing only the first letters. The real listed console output is below:
looking for healthselect of texas in away from home care
healthselect
of
texas
looking for h in a
looking for h in w
looking for h in a
looking for h in y
looking for e in a
looking for e in w
looking for e in a
looking for e in y
looking for a in a
looking for a in w
looking for a in a
looking for a in y
C# code:
public bool inStringAll(string needle, string haystack)
{
needle = Regex.Replace(needle.ToLower(), #"\r\n", string.Empty);
haystack = Regex.Replace(haystack.ToLower(), #"\r\n", string.Empty);
Console.WriteLine($"looking for {needle} in {haystack}");
string[] needleArr = needle.Split(' ');
string[] haystackArr = haystack.Split(' ');
for(int j = 0; j < needleArr.Length; j++)
Console.WriteLine(needleArr[j]);
int percent = 0;
int increment;
bool decision = false;
if (needleArr.Length > 3)
increment = 100 / 3;
else increment = 100 / needleArr.Length;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < haystackArr.Length; j++)
{
Console.WriteLine("looking for " + needle[i] + " in " + haystack[j]);
if (needleArr[i] == haystackArr[j])
{
percent += increment;
}
}
}
Console.WriteLine($"Percent: {percent}%");
if (percent >= 50)
decision = true;
return decision;
}
Has anyone worked with an emulator of this kind and had any issues getting these values correctly? I've worked with old attachmate systems using EXTRA! Basic and there was no issues, but this is my first client with IBM systems using C#.net so it may be different.

Find a string in a Range using ClosedXML C#

I want to be able to find if a particular string exists in a range using ClosedXML, however, I cannot find any find command in the documentation. Currently I loop through 1000s of rows to find if the string exists. Is there a more efficient way to do this?
Here is an example of my code:
for (int j = 3; j <= PipeSheet.LastRowUsed().RowNumber(); j ++)
{
if ((PipeSheet.Cell(j, ProdCodeColumnInPipe).Value.ToString().Trim() == SheetToEdit.Cell(i, ProdCodeColumnInMain).Value.ToString().Trim() & PipeSheet.Cell(j, 3).Value.ToString().Trim() == SheetToEdit.Cell(i, RegionCodeInMain).Value.ToString().Trim()))
{
SheetToEdit.Cell(i, ColumnToEdit).Value = "+";
if ((new[] { "Open", "Under Review" }).Contains(PipeSheet.Cell(j, 5).Value.ToString().Trim()) & (new[] { "Forecast"}).Contains(PipeSheet.Cell(j, 4).Value.ToString().Trim()))
{
if (FirstColumnHighlight > 1 & LastColumnHighlight > 1)
{
for (int k = FirstColumnHighlight; k <= LastColumnHighlight; k++)
{
SheetToEdit.Cell(i, k).Style.Fill.BackgroundColor = XLColor.FromArgb(255, 255, 0);
}
}
}
}
}
Firstly, your goal is best solved using conditional formatting.
But to answer your question, you can search for a string:
sheet.CellsUsed(cell => cell.GetString() == searchstring)
Reference: https://github.com/ClosedXML/ClosedXML/wiki/Better-lambdas
-- UPDATE --
There is a pull request at https://github.com/ClosedXML/ClosedXML/pull/399 to help with this, for example:
foundCells = ws.Search("searchText", CompareOptions.OrdinalIgnoreCase);

Getting the column totals in a 2D array but it always throws FormatException using C#

I am planning to get an array of the averages of each column.
But my app crashes at sum[j] += int.Parse(csvArray[i,j]); due to a FormatException. I have tried using Convert.ToDouble and Double.Parse but it still throws that exception.
The increments in the for loop start at 1 because Row 0 and Column 0 of the CSV array are strings (names and timestamps). For the divisor or total count of the fields that have values per column, I only count the fields that are not BLANK, hence the IF statement. I think I need help at handling the exception.
Below is the my existing for the method of getting the averages.
public void getColumnAverages(string filePath)
{
int col = colCount(filePath);
int row = rowCount(filePath);
string[,] csvArray = csvToArray(filePath);
int[] count = new int[col];
int[] sum = new int[col];
double[] average = new double[col];
for (int i = 1; i < row; i++)
{
for (int j = 1; j < col; j++)
{
if (csvArray[i,j] != " ")
{
sum[j] += int.Parse(csvArray[i,j]);
count[j]++;
}
}
}
for (int i = 0; i < average.Length; i++)
{
average[i] = (sum[i] + 0.0) / count[i];
}
foreach(double d in average)
{
System.Diagnostics.Debug.Write(d);
}
}
}
I have uploaded the CSV file that I use when I test the prototype. It has BLANK values on some columns. Was my existing IF statement unable to handle that case?
There are also entries like this 1.324556-e09due to the number of decimals I think. I guess I have to trim it in the csvToArray(filePath) method or are there other efficient ways? Thanks a million!
So there are a few problems with your code. The main reason for your format exception is that after looking at your CSV file your numbers are surrounded by quotes. Now I can't see from your code exactly how you convert your CSV file to an array but I'm guessing that you don't clear these out - I didn't when I first ran with your CSV and experienced the exact same error.
I then ran into an error because some of the values in your CSV are decimal, so the datatype int can't be used. I'm assuming that you still want the averages of these columns so in my slightly revised verion of your method I change the arrays used to be of type double.
AS #musefan suggested, I have also changed the check for empty places to use the IsNullOrWhiteSpace method.
Finally when you output your results you receive a NaN for the first value in the averages column, this is because when you don't take into account that you never populate the first position of your arrays so as not to process the string values. I'm unsure how you'd best like to correct this behaviour as I'm not sure of the intended purpose - this might be okay - so I've not made any changes to this for the moment, pop a mention in the comments if you want help on how to sort this!
So here is the updated method:
public static void getColumnAverages(string filePath)
{
// Differs from the current implementation, reads a file in as text and
// splits by a defined delim into an array
var filePaths = #"C:\test.csv";
var csvArray = File.ReadLines(filePaths).Select(x => x.Split(',')).ToArray();
// Differs from the current implementation
var col = csvArray[0].Length;
var row = csvArray.Length;
// Update variables to use doubles
double[] count = new double[col];
double[] sum = new double[col];
double[] average = new double[col];
Console.WriteLine("Started");
for (int i = 1; i < row; i++)
{
for (int j = 1; j < col; j++)
{
// Remove the quotes from your array
var current = csvArray[i][j].Replace("\"", "");
// Added the Method IsNullOrWhiteSpace
if (!string.IsNullOrWhiteSpace(current))
{
// Parse as double not int to account for dec. values
sum[j] += double.Parse(current);
count[j]++;
}
}
}
for (int i = 0; i < average.Length; i++)
{
average[i] = (sum[i] + 0.0) / count[i];
}
foreach (double d in average)
{
System.Diagnostics.Debug.Write(d + "\n");
}
}

How do I write data column b y column to a csv file

I have a big problem with writing some data to a csv file. I have a lot of measurement values. Every value is described by name, unit, value. So i want to build for every value a column with these three properties.
I want to store it into the csv file like this:
Width Cell Wall Thickness Coarseness Curl-Index etc.
mm mm mg/m % etc.
16,2 3,2 0,000 11,7 etc.
Till now i was coding a header for the names, another for the units and the values (that were previously stored into a string array) i just wrote in one line.
Till now my csv file looks like this:(
Width;Cell Wall Thickness;Coarseness;Curl-Index;etc.
mm;mm;mg/m;%;etc.
16,2;3,2;0,000;11,7;etc.
if it were not many values i wouldn't care about this but there are a lot so when i open the csv file there's the problem that the headers dont fit to the values and units. It's not organized, i cannot match the values to the headers.
I would like everything to be organized in columns. Any help would be strongly appreciated!
That's the code that i have till now:
StreamWriter sw = new StreamWriter("test2.csv");
int RowCount = 3;
int ColumnCount = 4;
string[][] Transfer_2D = new string[RowCount][];
Transfer_2D[0] = new string[3]{"Width", "CWT", "Coarseness", "Curl-Index"};//name of the values
Transfer_2D[1] = new string[3] {"mm", "mm", "mg/m", "%"}; //units
Transfer_2D[2] = new string[3] { TransferData[0], TransferData[1], TransferData[2], TransferData[3] };
for (int i = 0; i < RowCount; i++)
{
for (int j = 0; j < ColumnCount; j++)
{
sw.Write(Transfer_2D[i][j]);//write one row separated by columns
if (j < ColumnCount)
{
sw.Write(";");//use ; as separator between columns
}
}
if (i < RowCount)
{
sw.Write("\n");//use \n to separate between rows
}
}
sw.Close();
}
you can set the string to a fixed length.
example look here: (.NET Format a string with fixed spaces)
int iWantedStringLength = 20;
string sFormatInstruction = "{0,-" + iWantedStringLength.ToString() + "}";
for (int i = 0; i < RowCount; i++)
{
for (int j = 0; j < ColumnCount; j++)
{
sw.Write(String.Format(sFormatInstruction, Transfer_2D[i][j]));//write one row separated by columns
if (j < ColumnCount)
{
sw.Write(";");//use ; as separator between columns
}
}
if (i < RowCount)
{
sw.Write("\n");//use \n to separate between rows
}
}
For CSV work I use http://joshclose.github.io/CsvHelper/, this is a very nice helper class but it would require you to change your working a little bit.
I would advice you create a class to store each entry in and then create a "Mapper" to map it to csv fields. Then you can just pass a collection of objects and your mapping class to the helper and it produces a structured CSV.
There are alot of examples on that page so it should be straight forward for you to work through.

Using Excel Double Value in C#

I'm trying to get double values from Excel to my C# project. But, when I try that, Visual Studio automatically erases the comma/period, and shows the number without them.
For Example:
Excel: 192,168 or 192.168
C#: 192168,00
How can I prevent this from happening?
Excel Get-Value Code:
for (int i = 0; i < dataGridView1.ColumnCount; i++)
{
for (int j = 0; j < dataGridView1.Rows.Count - 1; j++)
{
tsp.addArray(Convert.ToDouble(ds.Tables["Deneme"].Rows[i][j].ToString()), i, j);
}
}
Replace is good way to do it i guess.
Just try like that.
string oldString = ds.Tables["Deneme"].Rows[i][j].ToString(); // Old string in addArray.
string convertedString = oldString.Replace(".",","); // Replacer for dots.
double convertedDouble = Convert.ToDouble(convertedString); // Convert double now.
I think your culture is tr-TR that's why your NumberDecimalSeparator is , not .
That's why when you write 192.168 in your program, it read its as hundred and ninety-two thousand ... but when you write 192,168 hundred and ninety-two ...
If your excel cell is like 192,168, there is no problem. Convert.ToDouble works exactly as you want;
string s = "192,168";
double d = Convert.ToDouble(s, CultureInfo.GetCultureInfo("tr-TR"));
Console.WriteLine(d); //192,168
But if your excel cell is like 192.168, then you need to use n0 format like;
string s = "192.168";
double d = 0;
if(s.Contains("."))
{
d = Convert.ToDouble(s, CultureInfo.GetCultureInfo("tr-TR"));
}
Console.WriteLine(d.ToString("n0")); //192.168

Categories