Auto incrementing w/ a vb.net chart control - vb.net

I'm curious to know if the DataVisualization.charting.chart in vb.net does any auto counting / plotting for my particular issue.
I have a file with thousands of User Agent Strings which were generated over a period of time. The UA Strings are generated from user logins.
In my program, I am identifying approximately 45 different environments as: Operating Systems + Browser Type (ie., "Windows 7 + IE10"). Each login also has a date stamp in the format of YYYY-MM.
My task is to do a line chart where I have Environment (Y-axis) vs Date (X-axis) using the vb.net charting control. I would like the control to increment each time I have a particular data set rather than keeping a hideous amount of arrays & counter data for my chart.
Does the vb.net charting control auto increment in this way? I am not able to find anything so far.

I'm not sure I understand the question (what is it that you want to auto increment? The axis min/max? The date? Something else?), but if you want the axes to update each time you add a new point, the chart certainly supports that. Just call Chart.ResetAutoValues() after you add the new point(s), and it will figure out new ranges for both axes.
Edit: Arrange your data before adding it to the chart. Something like:
Dictionary<string, int> values = new ...;
string[] uaStrings = ReadFileOfUAStrings();
foreach (string uaString in uaStrings)
{
values[uaString]++;
}
foreach (KVP in values)
{
chart.Series(kvp.Key).Points.Add(kvp.Value);
}
The above doesn't separate things out by date, but you should get the idea. As written, it's also not very efficient if another UA string is added to the file and the whole thing is re-read, but optimizations can come after it's functional.

Related

LabVIEW Inserting/overwriting text into existing string

I was wondering if folks have found a reliable way to inject text into an existing string. Some context, I'm writing data to a string indicator formatted like a table, and I wanted to inject values into so they maintain a specific format, spacing-wise. Writing to a table would definitely be easier, however I am porting a legacy program and wanted to provide familiarity to the end user.
Essentially, I want to do the equivalent of typing into a .txt file with the INSERT function enabled, where it just overwrites the content already in the string. Example below (dashes added to show spacing) of how it is currently looking when I inject the values with hard coded spacing:
Time---value---avg. value---result
60------10---------20---------PASS
120------11---------20---------PASS
180------9---------15---------FAIL
I'd prefer it to look more lined up, like below:
Time---value---avg. value---result
60------10---------20---------PASS
120-----11---------20---------PASS
180-----9--------- 15---------FAIL
Writing my application using LabVIEW 2019
Edit: Header will obviously not change, only each subsequent line where the values can result in entries not looking lined up
What about "Replace Substring" function (https://zone.ni.com/reference/en-XX/help/371361R-01/glang/replace_substring/)? Doesn't it meet your requirements?
The diagram below outputs 01234999990123PASS890123456789. The values of the integer and the word PASS are added replacing characters in the existing string, exactly like overstrike would do.

How to change number formatting for Hana SQL query session or connection?

For our customers that use SAPB1 with HanaDB we execute the same query to pull data out (using the ADO.NET interface). Some have their regional system systems that appear to control numerical formatting according to their locale, etc.
Say for example when executing: SELECT RDR1."Quantity" FROM RDR1
For a customer in the USA, RDR1."Quantity" = 2.000000
For a customer in Germany, RDR1."Quantity" = 2,000000 (notice the comma vs decimal)
I assume the actual database storage of the value is the same, it is just the query engine that is applying default system formatting based on the settings that makes the end result formatted one way or another.
Now, using a brute force approach and per column this type of change can be made:
REPLACE(CAST(ROUND(RDR1."Quantity",2) AS DECIMAL(10,2)), ',', '.') AS "Quantityā€¯
to give me "2.00"
However we have many columns like this and we want to make the code usable in all cases vs having multiple instances of the same queries for different regions -- and it just seems there should be a way to tell the query engine to return values as if it were in the USA and ignore default system locale and currency settings.
Question: Is it possible to make a high level setting change instead of per column formatting/casting - either using Hana SQL query code (like a session variable or something) or a connection setting when we establish the ADO.NET connection to HanaDB that will just make the values come out as if they were in the USA?
I haven't found any yet but perhaps it is not so easily found in the documentation how to handle it.
No, there is no HANA setting that would define how the application, SAP Business One in your case, renders the data to the user screen.
For SAP B1 you can find the documentation for setting these user settings here.
These settings include "thousands separator", "separator", "decimal places", and others.
But on HANA DB level, there is no global setting for that.
Also, the REPLACE workaround mentioned turns the input number data into a string, losing all the number semantics (ordering, mathematical operations) and increase the memory requirements for those values.
Rather avoid this technique if possible.
If you want to alter the decimal separator of the program output, just tell it to .NET.
An option is to set the Current Thread's Culture like in this snippet:
using System;
using System.Globalization;
class Program
{
static void Main(string[] args)
{
decimal d = 2021.1002m;
Console.WriteLine("Current Culture is {0}.", System.Threading.Thread.CurrentThread.CurrentCulture.Name);
Console.WriteLine("d = {0}.", d);
System.Threading.Thread.CurrentThread.CurrentCulture =
new CultureInfo("en-US");
Console.WriteLine("Current Culture now is {0}.", System.Threading.Thread.CurrentThread.CurrentCulture.Name);
Console.WriteLine("And d = {0}.", d);
}
}
For me the ouput is:
Current Culture is es-ES.
d = 2021,1002.
Current Culture now is en-US.
And d = 2021.1002.

Formatting duration for display

In a SAP database there are values formatted as PxDTyH where x is the number of days and y is the number of hours. A value like P2DT0H is 2 days + 0 hours. I can see that via SE16:
Unfortunately, this is exactly displayed like that to the user, "3" corresponds to the index in the database (not seen in the screenshot above).
I'd like to see it displayed
without the index (changing the options "show keys within drop-down lists" did not have an effect)
instead of the technical name P2DT0H I'd like to see "2 days and 0 hours" (or similar)
Is there a way to process the data before it gets displayed in the combo box? The developers can't change the format in the database because it would change the API.
FYI: I'm just a tester, I don't know how to code in ABAP, but from knowledge of other programming languages, I'd say that the data can be converted before it's displayed. I don't need a fully-fledged answer, just a pointer to a SAP hook or event which enables writing a conversion function.
Probably, conversion routines can be an option for you. What you should do is to:
Take your domain (which is used for PxDTyH values) or create new one specially for this.
Create FM with name CONVERSION_EXIT_%NAME%_OUTPUT, and put conversion logic in there. Mandatory parameters INPUT and OUTPUT should exist.
Enter the %NAME% into Convers.routine field in domain properties.
Enable Check conversion exits checkbox in user parameters.
More info is here.

Need Help Creating Custom Sorter On ObjectListView

Ok, I'm totally at a loss with this....
I think I have looked at every example and every code snippet around and still can't work out how to implement a custom sorter on my ObjectListView.
My primary column (column 0) contains numbers only (as a string) but is sorting all items by alphanumeric instead of numeric, meaning that it is doing something like this:
1
11
111
2
22
etc.
I am trying to find a relatively simple example of how to modify my ObjectListView to sort column 0 when it first loads, but I'm struggling.
I have converted over a custom class called ColumnSorter (from CodeProject) into VB and I'm calling the following delegate:
lvwColumnSorter = New CustomLVSorter.CustomLVSorter()
lsv_OpenTickets.CustomSorter = Sub(column As OLVColumn, order As SortOrder)
lvwColumnSorter.ColumnToSort = Ticket_Status.Index
lvwColumnSorter._SortModifier = CustomLVSorter.CustomLVSorter.SortModifiers.SortByText
lvwColumnSorter.OrderOfSort = SortOrder.Ascending
lsv_OpenTickets.ListViewItemSorter = lvwColumnSorter
End Sub
I get no errors, but I also get no change.
Any help would be greatly appreciated.
Well, are you sure you have looked at every example? I think there are a lot of resources on this one.
When you're using a list, datagridview, or any main form, you can adjust it to use a custom sorter. You create a custom IComparer, i.e. the definition of how you sort something. It can be as simple as converting the string (like yours) to an int with CInt() and returning -1 or +1 if it is greater or less than the last value. This is very common.
If you need help on the basics of how to do it, of course there are always the microsoft links that give you the basics such as Custom Sort I Comparer. But there is a stack flow that also follow your problem here: Custom sort C#
It's in C#, but there are many converters on that around here.
But the easiest way to get around it? Convert your string list into a integer list. Then it will sort perfectly.

Searching Multiple Results using Streamreader

Does anyone know of a method that allows you to search a string through a text file using StreamReader that allows you to account for multiple instances of finding the results. Basically I am creating a booking application and each time a customer books a seat, their PrimaryKey, FirstName, LastName and the co-ordinates of the seat on a data grid (which I have used as a method to book seats) are generated then saved to a text file.
I want the ability to be able to read multiple instances of a PrimaryKey then find the seat co-ordinates of each line that this PrimaryKey is listed on and repopulate another similar datagridview with these co-ordinates which is all going to be driven by a combobox index change.
It seems a bit complicated to understand but if anyone can help then please let me know.
I just need the knowhow of how to search multiple instances, so after its found the string once then look through the rest of the file to find another instance, I can do the rest by myself.
I'm coding using Visual Basic.Net
Yes it's possible to search multiple times through a file, but you'd either have to reopen the file, or rewind the stream (FileStream.Seek).
Wildly inefficient though.
If it has to remain an unsorted and unstructured file, build an in memory index to it.
If your key is an integer, create a Dictionary<int,int> of Key and Position in the stream.
Then when you want find key X you use FileStream.Seek to move to it, and read a line to get the data. If you find yourself grouping by say aeroplaneID, build a Dictionary<Int, List<Int,Int>>
where the key is the aeroplane id and the list is a list of primary keys and positions in the file.
You could push all that off to a background thread. You could try and get really clever and build them up as you need them. Personally though I'd be trying to move my storage to a more suitable format. You aren't struggling to do this because you've missed a class, you are struggling because you shouldn't.
Something like
Dictionary<int, int> _fileIndex = new Dictionary<int,int>();
using(FileStream fs = new FileStream(DataFileName,FileMode.Open,FileAccess.Read))
{
StreamReader reader = new StreamReader(fs);
int lastPosition = 0;
string currentLine = null;
while(currentLine = reader.ReadLine() != null)
{
String[] data = currentLine.Split(new char[] {','});
int key = int.Parse(data[0]);
fileIndex.Add(key,lastPosition);
lastPosition = fs.Position;
}
}
NB didn't test the above and there should be a bit more error checking in it. If there's alot of data in the line, then might be better off not suing split and just pulling out everything up to the correct delimiter. Also be careful how many indexes you keep live, wouldn't be long before they used up more space than just reading the entire thing in to memory.
Then you could create a class or structure to implement a line in the file, and write a bit of code
to use FileStream.Seek) to get there. If you wanted to load up a bunch of 'em it would make sense to get your list of positions of each one in the file and then sort them in order, then you could rip through the file in it's 'order' picking them out.