How can I loop thorough a record one character at a time? - datastage

How can I loop thorough a record one character at a time? I want to interrogate records in a ASCII file one character at a time looking for and replacing non-printable characters. I tried using the Loop Condition with no luck. Thanks in advance for any help.

Yes, this is possible in a DataStage Transformer.
The "Loop Condition" creates a new output row per iteration. It operates on each row it receives. You might want to add a constraint to your output link which is only true when your loop iterations are finished (for that row).
A little pseudo-code to replace every 'ä' with a '?' by looping through char-by-char:
// Input Link "DSLink2"
// provides a column named "text"
// Stage Variables:
NVarCHar(20) svLine := DSLink2.text
NChar(1) svReplacementChar := "?"
// Loop Variables:
NChar(1) lvCharToTest
Bit lvCharOK := 0
NVarCHar(20) lvNewLine := ''
Integer i := 0
// Loop Condition:
loop while (i < Len(svLine)) {
i = i + 1
lvCharToTest := svLine[i,1]
// replace by proper test condition or function according to your needs:
lvCharOK := lvCharToTest = 'ä'
if (lvCharOK) {
lvNewLine = lvNewLine + lvCharToTest
}
else {
lvNewLine = lvNewLine + svReplacementChar
}
}
// DSLink4_output:
If (i = Len(svLine)) {
DSLInk4_output.text := lvNewLine
}
Screenshot of a Transformer Stage showing this example

Related

Why is the key of my Associative Array a reference to a string and not the string itself?

I have the following string that contains product barcodes:
4016241030924;4016241030924;8710624237479;5900951254741;8710398162939;8710398162939;8710398162939;8710398162939;8710398162939;8710398162939;8710398162939;8710398162939;8710624296933;8710624296872;8710624223885;8710624223885;8711000341001;8711000341001;8711000341001;8710624260415;8710624260415;8710624260415;8710624260415;8710624260415;8710624260415;8710624260415;8710624260415;8710624260415;8710624260453;
What I want to do is:
Split the string by ;
Create an Associative Array where the key is the barcode and the value is the count of the barcode
Loop through the Associative Array and print the key (= barcode) and the value (= count)
Here's what I am trying:
BarcodesAssArray := Array()
BarcodeArray := StrSplit(fileContent, ";")
Loop % BarcodeArray.MaxIndex() - 1 {
thisBarcode := BarcodeArray[a_index]
; Check if barcode already exists
if (BarcodesAssArray[thisBarcode]) {
BarcodesAssArray[thisBarcode] := BarcodesAssArray[thisBarcode] + 1
} else {
BarcodesAssArray[thisBarcode] := 1
}
}
For key, value in BarcodesAssArray
MsgBox, %key% = %value%
But instead of the key being the barcode it is some sort of reference to the barcode. This is what I get:
-333809963 = 1
204486651 = 8
430547597 = 2
430561191 = 1
430584127 = 9
43084165 = 1
...
What I expect to get is:
4016241030924 = 2
8710624237479 = 1
8710398162939 = 8
...
What should I do differently?
Try to simplify the code and take it one step at time
BarcodesAssArray := 4016241030924;4016241030924;8710624237479;5900951254741;8710398162939
BarcodeArray := StrSplit(BarcodesAssArray, ";")
MsgBox BarcodeArray(1) BarcodeArray(2) BarcodeArray(3) BarcodeArray(4) BarcodeArray(5)
This will at least get you past the StrSplit statement knowing that you have a valid array
I haven't coded in a while so run at your own risk :)
"Your problem is probably occurring because the keys in your arrays are being treated as numeric. There are limits on the size of numeric keys, depending on whether you are using 32 bit AutoHotkey or 64 bit. The way I would fix this is to cause the keys to be treated as alpha by appending a constant alpha value to the key in the array and stripping it off when displaying, etc the key. This also deals with the case where leading zeros would otherwise be stripped from the numeric keys."
TAC109 - https://www.autohotkey.com/boards/viewtopic.php?p=312566#p312566
BarcodesString := "4016241030924;4016241030924;8710624237479;5900951254741;8710398162939;8710398162939;8710398162939;8710398162939;8710398162939;8710398162939;8710398162939;8710398162939;8710624296933;8710624296872;8710624223885;8710624223885;8711000341001;8711000341001;8711000341001;8710624260415;8710624260415;8710624260415;8710624260415;8710624260415;8710624260415;8710624260415;8710624260415;8710624260415;8710624260453;"
BarcodesString := RTrim(BarcodesString,";") ; remove trailing ;
BarcodesAssArray := {}
Loop, Parse, BarcodesString, `;
switch BarcodesAssArray.HasKey(A_LoopField . "")
{
case true:BarcodesAssArray[A_LoopField . ""] += 1
case false:BarcodesAssArray[A_LoopField . ""] := 1
}
For key, value in BarcodesAssArray
MsgBox, %key% = %value%
Xtra - https://www.autohotkey.com/boards/viewtopic.php?p=312565#p312565

Looking up data from a file, and storing them as variables

I'm new to autohotkey and I can't figure out how to solve this. Any help is appreciated.
I have list.txt which includes ids and names like this:
list.txt:
123124 - whatever
834019 - sometext
3980 - afjalkfj
I need a function that can do the following
lookup(id, name){
** The function here should lookup for the id inserted
then save ONLY the data related to it in variable x (not the full line)
}
Example
lookup(834019, x)
%x% = sometext
Please help me to do this. Thanks!
What you need in this case are
FileRead to read the file's contents into a variable.
A parsing loop to parse the text of each line.
The StrSplit() function to split the text of each line into an
array of Substrings using the specified Delimiters.
The second parameter (name) is redundant in this case. You can omit it:
x := lookup(834019)
MsgBox, % x
MsgBox, % lookup(3980)
lookup(id) {
FileRead, Contents, list.txt ; read the file's contents into the variable "Contents"
if not ErrorLevel ; Successfully loaded.
{
Loop, parse, Contents, `n, `r ; parse the text of each line
{
word_array1 := StrSplit(A_LoopField," - ").1 ; store the first substring into the variable "word_array1"
word_array1 := Trim(word_array1, " `t") ; trim spaces and tabs in this variable
If (word_array1 = id)
{
name := StrSplit(A_LoopField," - ").2
name := Trim(name, " `t")
return name
}
}
Contents := "" ; Free the memory.
}
else
MsgBox, A problem has been encountered while loading the File Contents
}

How to have "input" (or is it context?) dependent hotstrings/hotkeys ?

I want a hotkey or hotstring (whatever is easier), so I can easily convert e.g.
1:5 into [1,2,3,4,5] or
3:7 into [3,4,5,6,7] etc..
I want this to work for all integers...
So I want "multiple variants of the same hotstring" (or, if easier: a hotkey that works somewhat similar: e.g. pressing strg + h and typing 1:3 should produces [1,2,3] )
It should recognize that I typed a number followed by colon followed by another number, and then expand correspondingly..
I looked into the Input function, but it does not seem to be exactly what I want..
I don't need a working solution. Hints & links or keywords for further googling are already helpful..
After typing +h or pressing strg+h, type two numbers to produce the desired outcome:
:*:+h::
^h::
nr := "" ; empty variable's content
end_nr := ""
Input, var, L2 ; Length limit=2
; Input, var, L2 V ; V: Visible
If var is not integer
{
MsgBox, "%var%" is not integer
return
}
first_nr := SubStr(var, 1, 1)
second_nr := SubStr(var, 0)
if (first_nr >= second_nr)
{
MsgBox, "%first_nr%" is greater or equal "%second_nr%"
return
}
Loop
{
nr++ ; increase the number in the variable "nr" by 1 in each iteration
if (nr < first_nr)
continue
If (nr = second_nr)
break
end_nr .= nr . "," ; concatenate the outputs by adding a comma to each one
}
If (first_nr = 0)
MsgBox, "0,%end_nr%%second_nr%"
else
MsgBox, "%end_nr%%second_nr%"
return

Auto hotkey - Splitting String and checking for numeric values

I'm a fairly new developer and i have run into a problem.
I'm using auto hotkey to automate at longer manual process, and one of the things i'm trying to do is split an address, and then use each individual part of that address in another system. The problem is that addresses can be very different.
I use Strsplit on the entire address, and then i want to check if each part of that address is numerical or a letter.
My problem is that no matter what i try. I always get the same result.
I use "if var is not type" and "if var is type". The problem is that not matter I check for alpha, integer, number or float it always returns true even if the variable is clearly a string and I check for numbers. Sample code below.
xl := ComObjActive("Excel.Application")
Array := StrSplit(xl.Range("C2").text, A_Space, ",")
if Array[1] is not number
{
Msgbox, False
}
if Array[1] is number
{
Msgbox, True
}
Can you help me?
To retrieve an array element use the := operator:
xl := ComObjActive("Excel.Application")
Array := StrSplit(xl.Range("C2").text, A_Space, ",")
element1 := Array[1]
; MsgBox, % element1
if element1 is not number
Msgbox, False
if element1 is number
Msgbox, True

Remove last n characters of string after the dot with Autohotkey

I am using Autohotkey.
I have a string that looks like this S523.WW.E.SIMA. I want to remove the last few characters of the string after the dot (including the dot itself). So, after the removal, the string will look like S523.WW.E.
This may look like a simple question but I just cannot figure out using the available string functions in Autohotkey. How can this be done using Autohotkey? Thank you very much.
Example 1 (last index of)
string := "S523.WW.E.SIMA"
LastDotPos := InStr(string,".",0,0) ; get position of last occurrence of "."
result := SubStr(string,1,LastDotPos-1) ; get substring from start to last dot
MsgBox %result% ; display result
See InStr
See SubStr
Example 2 (StrSplit)
; Split it into the dot-separated parts,
; then join them again excluding the last part
parts := StrSplit(string, ".")
result := ""
Loop % parts.MaxIndex() - 1
{
if(StrLen(result)) {
result .= "."
}
result .= parts[A_Index]
}
Example 3 (RegExMatch)
; Extract everything up until the last dot
RegExMatch(string, "(.*)\.", result)
msgbox % result1
Example 4 (RegExReplace)
; RegExReplace to remove everything, starting with the last dot
result := RegExReplace(string, "\.[^\.]+$", "")