UiPath how to get Type of generic Value - uipath

Background Story
I have an excel table of values with thousands seperator . and floating point seperator ,.
If the number is lower than 1000, therefore only the , exists. In UiPath, I'm using a read range and store the data in a data table. Somehow, Uipath manages to replace the , by a . because it interprets the value as float. But this only happens to values lower than 1000. Larger numbers are interpreted as string and all the seperators stay the same.
Example:
+───────────+───────────────+─────────+
| Input | UiPath Value | Type |
+───────────+───────────────+─────────+
| 4.381,14 | 4.381,14 | String |
| 5.677,50 | 5.677,50 | String |
| 605,27 | 605.27 | Double |
+───────────+───────────────+─────────+
Problem
I want to loop through the data table and apply some logic to each value. Because of the different data types, I assign the value to a generic value variable. It is a huge problem that the , is automatically replaced by a ., because in my context, this is a completely different value. Therefore I somehow need to check the data type, so i can replace the seperator again.
Attempt
I'm trying to get the type by GetType().ToString(), but it only delivers me: UiPath.Core.GenericValue

I tried to replicate it. And I have successfully converted to double using the following steps. I have taken one value and followed the below steps.
strValue = dt(0)(0).ToString.Replace(".","$")
strValue = strValue.Replace(",",".")
strValue = strValue.Replace("$",",")
dblValue = CDbl(strValue)
In UiPath, when we read data from Excel, it will be treating the cell values as generic objects. So, we explicitly convert it to String.

Related

PROC FREQ in SAS gives too wide columns

I did a simple proc freq in SAS:
PROC FREQ DATA=test;
a * b;
RUN;
This raised the error: insufficient page size to print frequency table
From ERROR: Insufficient page size to print frequency table in SAS PROC FREQ I learned that the error is fixed by enlarging the page size:
option pagesize=max;
But then my table still looked strange with super high white spaces in column b:
Frequency |
Percent |
Row Pct | value 1 | value 2 |
Col Pct | | |
| | |
...etc... ...etc...
| | |
----------+----------+----------+
a | 12 | 3 |
What solved my problem was adding a format to the proc freq that truncated variable b.
PROC FREQ DATA=test;
FORMAT B $7.;
a * b;
RUN;
now my result looks like this and I'm happy enough:
Frequency |
Percent |
Row Pct |
Col Pct | value 1 | value 2 |
----------+----------+----------+
a | 12 | 3 |
I'm left a bit bewilderd, because nowhere in the code did I apply a format to b before, just a lenght statement. Other variables that had their lengths fixed did not have this problem. I did switch from an excel sourcefile to oracle-exadata as source. Is it possible that Oracle pushes variable formats to SAS?
SAS has a nasty habit of attaching formats to character variables pulled from external databases, including PROC IMPORT from an EXCEL file. So if a character variable has a storage length of 200 then SAS will also attach the $200. format to the variable.
When you combine two dataets that both contain the same variable the length will be set by the first version of the variable seen. But the format attached will be set by the first non-empty format seen. So you could combine a dataset where A has length $10 and no format attached with another dataset where A has the format $200. attached and the result will a variable with an actual length of 10 but the $200. format attached.
You can use the format statement where you list variable names but no format specification to remove them. You could do it in the PROC step.
PROC FREQ DATA=test;
tables a * b;
format _character_ ;
RUN;
Or do it in a data step or use PROC DATASETS to modify the formats attached to the variable in an existing dataset.

How to insert into semi sorted List?

I have a large semi sorted list of Strings sorted by only first character. Each String is accompanied by an ID. The first x entries start with letter A then follow entries starting with letter B and so on. Not all letters are necesarily represented.
By semi sorted I mean that there are exceptions (wrongly sorted entries). It is NOT possible to sort the entries in a correct fashion. Already existent entries have to remain at their ID.
I have crafted the follwing example only including starting letters A and B. The entries starting with C, Z and S have been wrongly entered.
Example:
| ID | NAME |
|------|------|
| 6000 | AXXX |
| 6001 | AXZS |
| 6003 | AAFD |
| 6004 | CSDF |
| 6005 | ZSSF |
| 6006 | ASDF |
| 6007 | BXAS |
| 6010 | BZDS |
| 6011 | SHZF |
| 6012 | BHZT |
I want to add entries to the list. A entry with a Name starting with letter A should be inserted grouped with other entries starting with letter A if possible or otherwise at the very end.
In the above example a entry with a Name starting with letter A should be inserted with ID 6002.
A entry with a Name starting with letter B should be added with ID 6008.
I am not sure how to solve this. My first thoughts are to first iterate over the existing list starting with the lowest ID and to save information on the letter group.
Like:
Letter: A StartID: 6000 EndID: 6006 IsFull:False
Letter: B StartID: 6007 EndID: 6012 IsFull:False
And then when it comes to inserting using the above information for the determination of possible IDs of the new entry. After inserting a new entry this information would have to be updated.
However I am not sure on how to exactly achieve this. All I need is some pseudo code for a possible solution so I can write my own code.
You probably want a few steps
find the position of the insertion group if it exists (what if the first few were B, Z, before A?)
find the last member of the group if it exists, otherwise the last member of the prior group (for example when inserting F)
determine if there's room before in the left index after the last member of the group, and before the first member of the next one
if a position exists for insertion, insert the value, else
find the last position
append the value
Some considerations
you must keep track of and consider several positions, some structure will help you with this
if you have runs ordered A,B,Z,C in the left column, does the block with Z comprise a group? is the block C misplaced? otherwise it seems your values should grow wherever the first new member is
"next" needs to consider multiple characters (presumably ABAA comes after AABB)

How to use hex color value in SSRS

When I set custom color to some form in Expressions window, the formula looks like
#117be0
or
="#117be0"
So, the question is, how to get string color hex value from dataset that contains the same value?
Something like this
=First(Fields!my_color.Value, "color_dataset")
Well, you kind of answered your own question. Yes, FIRST() will return the first value in the colors dataset. To make this more meaningful, you are going to want to used the LOOKUP function.
LOOKUP(Fields!Local_Dataset_Value.Value, Fields!Color_Dataset_Value.Value, Fields!my_color.Value, "color_dataset")
Lookup will check the value of the Local_Dataset_Value field in your current table dataset, and find a match for that value in the "color_dataset" dataset's Color_Dataset_Value field. When it finds a match, then your color will return.
To explain further, given datasets:
Dataset1
Name | Age | Etc
........................
Joe | 30 | Whatever
and
color_dataset
Color_Name | my_color
.....................
Joe | Blue
then:
LOOKUP(Fields!Name.Value, Fields!Color_Name.Value, Fields!my_color.Value, "color_dataset")
Would return:
"Blue"

grid filter in foxpro

I have a grid on a form that displays some columns from a dbf table and a textbox.
I want to search the value displayed in the textbox over all columns from a dbf table. Some fields are numeric and other are character
If I want to find a number, should search all record that contain that number in all columns, no matter the column type.
If I want to search a substring should give me all record that contain that substring.
SET FILTER TO ALLTRIM(ThisForm.Text1.Value) $Content or ALLTRIM(val(ThisForm.Text1.Value)) $registrationNumber or ALLTRIM(ThisForm.Text1.Value) $holderNo
Your approach with the "$" wildcard "contains" approach appears to be ok. However, your attempt via allt( val( )) would fail as you cant trim a numeric value, it would have to be pre-converted to a string.
Now, that said, you could shorten your query by just doing a $ against a concatenation of ALL columns something like (assuming your registration number is a numeric field)...
set filter to ALLTRIM(ThisForm.Text1.Value) ;
$ ( Content +"," +str(registrationNumber) +," + holderNo )
if you have dates or date/time fields you could do DTOC( dateField ) or TTOC( dateTimeField). So, by building a single string of all values, you dont have to explicitly repeat the OR condition repeatedly.
You could do something like:
select curGrid
scan
lcRow = transform(field1) + transform(field2) ... + transform(lastfield)
if lcSearchValue $ lcRow
DoWhatever()
endif
endscan
This leverages the fact that transform() will give a string representation of any data type.

Substituting string labels by integer IDs and back

My data files contain lines with the first entity being a string label followed by features. For example:
MEMO |f write down this note
CALL |f call jim's cell
The problem is that Vowpal Wabbit accepts only integer labels. How can I quickly change from string labels to unique integer IDs and back? That is quickly modify the data file to:
1 |f write down this note
2 |f call jim's cell
... and back when needed.
For my sample dataset I did it manually for each class using ``sed'', but this breaks seriously my workflow.
cat input.data | perl -nale '$i=$m{$F[0]}; $i or $i=$m{$F[0]}=++$n; $F[0]=$i; print "#F"; END{warn "$_ $m{$_}\n" for sort {$m{$a}<=>$m{$b}} keys %m}' > output.data 2> mapping.txt

Resources