VB 2010: How to index textbox (making it like slots)? - vb.net

If the title isn't clear; I want to be able to select any character from textbox without making some complex loops-dependent code (I can do that one). For example, let's consider this text is entered in a textbox:
hello user!
I want some syntax when I tell to get me the index 1's value, it gives me "h", for index 5 = "o"... etc
So, anyone knows what's the right syntax, please help!

string can be directly indexed without any special code.
//from metadata
public sealed class String : IComparable, ICloneable, IConvertible, IComparable<string>, IEnumerable<char>, IEnumerable, IEquatable<string>
{
....
// Summary:
// Gets the character at a specified character position in the current System.String
// object.
//
// Parameters:
// index:
// A character position in the current string.
//
// Returns:
// A Unicode character.
//
// Exceptions:
// System.IndexOutOfRangeException:
// index is greater than or equal to the length of this object or less than
// zero.
public char this[int index] { get; }
....
}
dim str = "hello";
dim hchar = str(0);
dim echar = str(1);
dim lchar = str(2);
ect

Dim x As String = "Hello"
Console.Write(x.IndexOf("e")) 'Would return the position
Console.Write(x(x.IndexOf("e"))) 'Would return the character based upon the position
Console.Write(x(1)) 'Returns the character based at position 1 of the string
You can remove the Console.Write if you are using a WinForm.
TextBox1.Text = x(x.IndexOf("e"))

This should work.
Dim orig = "hello user!"
Dim res = Enumerable.Range(0,orig.Length).[Select](Function(i) orig.Substring(i,1))
So then you can do:
Dim x = res(0) 'x = "h"

Related

How to serialize an object with newtonsoft, which has a value with backslash [\]

I prepared this small example to show you my problem (vb.net and Newtonsoft)
I would prefer that the solution be done with Newtonsoft.
Public Class Message
Property Emoji As String
End Class
Public Sub GetJson()
Dim msgObject As New Message With {.Emoji = "\uD83D\uDE00"}
'Option 1
Dim JsonSerializerSettings As New JsonSerializerSettings
JsonSerializerSettings.StringEscapeHandling = StringEscapeHandling.EscapeNonAscii
Dim msgJson_1 As String = Newtonsoft.Json.JsonConvert.SerializeObject(msgObject, JsonSerializerSettings)
'Option 2
Dim msgJson_2 As String = Newtonsoft.Json.JsonConvert.SerializeObject(msgObject, Newtonsoft.Json.Formatting.None)
'Option 3
Dim stringWriter As New StringWriter()
Using writer As New JsonTextWriter(stringWriter)
writer.Formatting = Formatting.None
Dim serializer As New JsonSerializer()
serializer.Serialize(writer, msgObject)
End Using
Dim msgJson_3 As String = stringWriter.ToString()
End Sub
with none of the three options works, it always results in
{
"Emoji": "\\uD83D\\uDE00"
}
The result I need is
{
"Emoji": "\uD83D\uDE00"
}
How do I set Newtonsoft to not take into account the backslash character, as an escaped character?
Another unorthodox way could be:
jsonString = jsonString.replace("\\","\")
I do not really like
Thanks!!!!
\ is an escape char in JSON hence if you try and serialise a \ it gets escaped as \\ then when you deserialise \\ you get \
My guess is you have been given an example asking you to send "Emoji": "\uD83D\uDE00"
In json (and C#) \u#### specifies a unicode character (usually for something not found on a keyboard) as you are using VB.NET instead you should use $"{ChrW(&HD83D)}{ChrW(&HDE00)}"
"jsonString = jsonString.replace("//","/") " will never work, this is more safe way
json = json.Replace("\\\\u","\\u");
or since you don't like old, good classical solutions
json = Regex.Replace(json, #"\\u", #"u");
//or
json = json.Replace(#"\\u", #"\u");
even this will work in your case ( but I will not recommend for another cases since it is not safe)
json = Regex.Unescape(json);

Reading long sequence of digit as string

I'm using EPPlus to read a customer database.
From time to time in a text cell I'm reading as string, the customer wrote a long sequence of digit
My code read it as exponential format.
Is there a way to force the reading as string?
Here's the code snippet I'm using
using (ExcelPackage xlPackage = new ExcelPackage(new FileInfo(xlsFile))) {
var myWorksheet = xlPackage.Workbook.Worksheets.First();
while (!string.IsNullOrEmpty(myWorksheet.Cells[rowNum, 1].GetValue<string>()))
{
var cell = myWorksheet.Cells[rowNum, 20];
var idDoc = cell.GetValue<string>(),
// do something with idDoc
rowNum += 1;
}
}
when the cell contains, let's say 1790002099190700, idDoc is "1,7900020991907E+15"
What you are seeing make sense as excel will store the value as a double like any other numeric value.
It looks like you are exporting from a database to excel. I would assume that when exported there is no formatting set in Excel in which case using the .Text value of the cell object simply fall back to "General" in excel.
Say you have this:
So, what you end up with is this:
[TestMethod]
public void Cell_Digits_As_String()
{
//https://stackoverflow.com/questions/58058900/reading-long-sequence-of-digit-as-string
var fi = new FileInfo(#"c:\temp\Cell_Digits_As_String.xlsx");
using (var package = new ExcelPackage(fi))
{
var workbook = package.Workbook;
var worksheet = workbook.Worksheets.First();
var valCell = worksheet.Cells[1, 1];
var valText = valCell.Text; //Applies "General" unless otherwise specified
var valValue = valCell.Value; //As a BOXED double
var valString = valCell.GetValue<string>(); //Falls back to ChangeType
Console.WriteLine($"Value as text: {valText} ({valText.GetType()})");
Console.WriteLine($" Same as: {((double)valValue).ToString("0.#####", new CultureInfo("es-US"))}");
Console.WriteLine($"Value as value: {valValue} ({valValue.GetType()})");
Console.WriteLine($" Same as: {valValue.ToString()}");
Console.WriteLine($"Value as string: {valString} ({valString.GetType()})");
Console.WriteLine($" Same as: {Convert.ChangeType(valValue, typeof(double)).ToString()}");
}
}
Which shows this in the out:
Value as text: 1790002099190700 (System.String)
Same as: 1790002099190700
Value as value: 1.7900020991907E+15 (System.Double)
Same as: 1.7900020991907E+15
Value as string: 1.7900020991907E+15 (System.String)
Same as: 1.7900020991907E+15
So, it would seem that using .Text is the most convenient to get what you want. But if you are concerned about the formatting being altered in any way or just want to be absolutely sure, just do:
try
{
((double)valCell.Value).ToString("0.#");
}
catch (Exception ex)
{
//Handle it...
}

How to get NPOI Excel RichStringCellValue?

I am using DotNetCore.NPOI (1.2.1) in order to read an MS Excel file.
Some of the cells are of type text and contain formatted strings (e.g. some words in bold).
How do I get the formatted cell value? My final goal: Retrieve the cell text as HTML.
I tried
var cell = row.GetCell(1);
var richStringCellValue = cell.RichStringCellValue;
But this won't let me access the formatted string (just the plain string without formattings).
Does anybody have an idea or solution?
I think you'll have to take longer route in this case. First you'll have to maintain the formatting of cell value like date, currency etc and then extract the style from cell value and embed the cell value under that style.
best option is to write extenstion method to get format and style value.
To get the fomat Please see this link How to get the value of cell containing a date and keep the original formatting using NPOI
For styling first you'll have to check and find the exact style of running text and then return the value inside the html tag , below method will give you idea to extract styling from cell value. Code is untested , you may have to include missing library.
public void GetStyleOfCellValue()
{
XSSFWorkbook wb = new XSSFWorkbook("YourFile.xlsx");
ISheet sheet = wb.GetSheetAt(0);
ICell cell = sheet.GetRow(0).GetCell(0);
XSSFRichTextString richText = (XSSFRichTextString)cell.RichStringCellValue;
int formattingRuns = cell.RichStringCellValue.NumFormattingRuns;
for (int i = 0; i < formattingRuns; i++)
{
int startIdx = richText.GetIndexOfFormattingRun(i);
int length = richText.GetLengthOfFormattingRun(i);
Console.WriteLine("Text: " + richText.String.Substring(startIdx, startIdx + length));
if (i == 0)
{
short fontIndex = cell.CellStyle.FontIndex;
IFont font = wb.GetFontAt(fontIndex);
Console.WriteLine("Bold: " + (font.IsBold)); // return string <b>my string</b>.
Console.WriteLine("Italics: " + font.IsItalic + "\n"); // return string <i>my string</i>.
Console.WriteLine("UnderLine: " + font.Underline + "\n"); // return string <u>my string</u>.
}
else
{
IFont fontFormat = richText.GetFontOfFormattingRun(i);
Console.WriteLine("Bold: " + (fontFormat.IsBold)); // return string <b>my string</b>.
Console.WriteLine("Italics: " + fontFormat.IsItalic + "\n");// return string <i>my string</i>.
}
}
}
Font formatting in XLSX files are stored according to schema http://schemas.openxmlformats.org/spreadsheetml/2006/main which has no direct relationship to HTML tags. Therefore your task is not that much straight forward.
style = cell.getCellStyle();
font = style.getFont(); // or style.getFont(workBook);
// use Font object to query font attributes. E.g. font.IsItalic
Then you will have to build the HTML by appending relevant HTML tags.

Increment String Value Google Sheet

Using the following code I cannot increment a value in google sheets to be plus one.
function incrementCellValuesByOne() {
// Increments the values in all the cells in the active range (i.e., selected cells).
// Numbers increase by one, text strings get a "1" appended.
// Cells that contain a formula are ignored.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var activeRange = ss.getActiveRange();
var cell, cellValue, cellFormula;
// iterate through all cells in the active range
for (var cellRow = 1; cellRow <= activeRange.getHeight(); cellRow++) {
for (var cellColumn = 1; cellColumn <= activeRange.getWidth(); cellColumn++) {
cell = activeRange.getCell(cellRow, cellColumn);
cellFormula = cell.getFormula();
// if not a formula, increment numbers by one, or add "1" to text strings
// if the leftmost character is "=", it contains a formula and is ignored
// otherwise, the cell contains a constant and is safe to increment
// does not work correctly with cells that start with '=
if (cellFormula[0] != "=") {
cellValue = cell.getValue();
cellValue =+cellValue
cell.setValue(cellValue + 1);
}
}
}
}
For example "personalDataDOB_3" needs to become "personalDaTaDOB_4" I'm looking for a fast way to do this as right now I need to replace the value by typing.
You want to modify "personalDataDOB_3" of a certain cell to "personalDaTaDOB_4". If my understanding is correct, how about this modification?
Modification points :
When the retrieved "personalDataDOB_3" is converted to the number using cellValue =+cellValue, NaN is returned. So even if 1 was added, the result is NaN.
If the format of strings you want to modify is always "personalDataDOB_#", how about separating the string by _?
In order to reflect above points, please modify your script as follows.
From :
if (cellFormula[0] != "=") {
cellValue = cell.getValue();
cellValue =+cellValue
cell.setValue(cellValue + 1);
}
To :
if (cellFormula[0] != "=") {
cellValue = cell.getValue();
var temp = cellValue.split("_"); // Added
temp[1] = Number(temp[1]) + 1; // Added
cell.setValue(temp.join("_")); // Modified
}
Note :
If the format of strings you want to modify is always changed, please tell me.
If I misunderstand your question, I'm sorry.

Lucene: how to preserve whitespaces etc when tokenizing stream?

I am trying to perform a "translation" of sorts of a stream of text. More specifically, I need to tokenize the input stream, look up every term in a specialized dictionary and output the corresponding "translation" of the token. However, i also want to preserve all the original whitespaces, stopwords etc from the input so that the output is formatted in the same way as the input instead of ended up being a stream of translations. So if my input is
Term1: Term2 Stopword! Term3
Term4
then I want the output to look like
Term1': Term2' Stopword! Term3'
Term4'
(where Termi' is translation of Termi) instead of simply
Term1' Term2' Term3' Term4'
Currently I am doing the following:
PatternAnalyzer pa = new PatternAnalyzer(Version.LUCENE_31,
PatternAnalyzer.WHITESPACE_PATTERN,
false,
WordlistLoader.getWordSet(new File(stopWordFilePath)));
TokenStream ts = pa.tokenStream(null, in);
CharTermAttribute charTermAttribute = ts.getAttribute(CharTermAttribute.class);
while (ts.incrementToken()) { // loop over tokens
String termIn = charTermAttribute.toString();
...
}
but this, of course, loses all the whitespaces etc. How can I modify this to be able to re-insert them into the output? thanks much!
============ UPDATE!
I tried splitting the original stream into "words" and "non-words". It seems to work fine. Not sure whether it's the most efficient way, though:
public ArrayList splitToWords(String sIn)
{
if (sIn == null || sIn.length() == 0) {
return null;
}
char[] c = sIn.toCharArray();
ArrayList<Token> list = new ArrayList<Token>();
int tokenStart = 0;
boolean curIsLetter = Character.isLetter(c[tokenStart]);
for (int pos = tokenStart + 1; pos < c.length; pos++) {
boolean newIsLetter = Character.isLetter(c[pos]);
if (newIsLetter == curIsLetter) {
continue;
}
TokenType type = TokenType.NONWORD;
if (curIsLetter == true)
{
type = TokenType.WORD;
}
list.add(new Token(new String(c, tokenStart, pos - tokenStart),type));
tokenStart = pos;
curIsLetter = newIsLetter;
}
TokenType type = TokenType.NONWORD;
if (curIsLetter == true)
{
type = TokenType.WORD;
}
list.add(new Token(new String(c, tokenStart, c.length - tokenStart),type));
return list;
}
Well it doesn't really lose whitespace, you still have your original text :)
So I think you should make use of OffsetAttribute, which contains startOffset() and endOffset() of each term into your original text. This is what lucene uses, for example, to highlight snippets of search results from the original text.
I wrote up a quick test (uses EnglishAnalyzer) to demonstrate:
The input is:
Just a test of some ideas. Let's see if it works.
The output is:
just a test of some idea. let see if it work.
// just for example purposes, not necessarily the most performant.
public void testString() throws Exception {
String input = "Just a test of some ideas. Let's see if it works.";
EnglishAnalyzer analyzer = new EnglishAnalyzer(Version.LUCENE_35);
StringBuilder output = new StringBuilder(input);
// in some cases, the analyzer will make terms longer or shorter.
// because of this we must track how much we have adjusted the text so far
// so that the offsets returned will still work for us via replace()
int delta = 0;
TokenStream ts = analyzer.tokenStream("bogus", new StringReader(input));
CharTermAttribute termAtt = ts.addAttribute(CharTermAttribute.class);
OffsetAttribute offsetAtt = ts.addAttribute(OffsetAttribute.class);
ts.reset();
while (ts.incrementToken()) {
String term = termAtt.toString();
int start = offsetAtt.startOffset();
int end = offsetAtt.endOffset();
output.replace(delta + start, delta + end, term);
delta += (term.length() - (end - start));
}
ts.close();
System.out.println(output.toString());
}