I am working on an excel vba macro which opens some files but I ran into a problem, some files have a special character and I cannot copy it to be able to make a replacement, I even tried to find the ASCII code but it throws me the same code as the common space, I can only see it in MS Word.
The tiny circle is the special char:
You can recognize characters in Word:
Sub PrintASCII()
s = Selection.Text
For i = 1 To Len(s)
Debug.Print Asc(Mid(s, i, 1))
Next
End Sub
Usage: select the symbols and run this Sub. See output in VBE Immediate window
Output
95
95
95
95
160
95
95
95
95
95
13
Related
I am trying to replace the tab with the expected output as "129hello3 78 0".Its showing same output after running the below mentioned lines of code.
I have given tab space between "129" and "3" and rest others are spaces
a="129 3 78 0"
b=a.replace('\t+','hello')
print(b)
There is no tab in a="129 3 78 0", but rather two spaces. For example, copy and paste tab from the text editor to ensure that the right character is in string a.
Here is the example:
a="129 3 78 0"
b=a.replace(' ','hello')
print(b)
a="129 3 78 0"
b=a.replace('\t','hello')
print(b)
The output is
129hello3 78 0
129hello3 78 0
In order to get this result, please open the editor of your choice (I am using Notepad here) paste the code there, and make sure that you have tab in required spaces (circled in red):
then copy the code from there and insert intoonline compiler of your choice ( I used https://www.programiz.com/python-programming/online-compiler/). Click Run
You are using replace instead of regex.
import re
a="129 3 78 0"
b=re.sub('[\t]+','hello', a)
print(b)
Or if you need replace:
a="129 3 78 0"
b=a.replace('\t','hello')
print(b)
I stumbled into RED language the other day and spend (more or less literally) the last 24h "learning" it. I exhausted my googling skills trying to find solution for a simple problem that just evades my skills and logic, so hopefully somebody here can lead me to path to righteousness.
As the title suggest, I tried to parse a simple string (any string of random text, really), get the individual char(acter)s and then tried to save them into a variable. (Another string/array/any type really)
The best I could do was with code using:
alpha: charset [#"a" - #"z"]
testString: "this is just random rambling to test parsing!"
as prerequisites and something like this when (trying to) parse:
probe parse teststring [copy text to alpha (append text2 to-integer(to-char text)) to end]
Saves the (first letter) ascii code to text2 and running the script several times properly adds the (same first letter) ASCII code several times in a row:
CONSOLE OUTPUT
>> probe parse teststring [copy text to alpha (append text2 to-integer(to-char text)) to end]
true
== true
>> probe text2
"34"
== "34"
>> probe parse teststring [copy text to alpha (append text2 to-integer(to-char text)) to end]
true
== true
>> probe text2
"3434"
== "3434"
Obviously my parsing is not really "looping" the individual characters of the string or not saving them properly while doing it. Maybe my parsing really takes the whole string from TO till END and I try to then convert that to ASCII code or something else is happening here?
ANY help will be greatly appreciated, as I cannot possibly advance with my RED learning before solving this dilemma and understanding how the parsing really works in RED.
I am not sure, if I understand your question and what you want to achieve, but if you are looking for all the ascii representation of the chars you can get that with
asciis: []
parse teststring [some [set a alpha (append asciis to-integer a )| skip]]
== true
>> asciis
== [116 104 105 115 105 115 106 117 115 116 114 97 110 100 111 109 114 97 109 98 108 105 110 103 116 111 116 101 115 116 112 97 114 115 105 110 103]
some is one of the available words responsible for the looping
There are some issues in your trial. It would give some errors before doing any conversion. text2 is probably declared before. to alpha would give an empty string "" as you try to copy up to the first alpha character. Remember to goes up to and not including the target. You can not convert an empty string to a character. If we assume until now no error occurred, then you are still in front of your string and you go straight to the end of your string.
Some documentation about Red parse. see Iteration about looping
You can debug your parsing either with parse-trace or just put a simple (probe text) after the part of your rule you want to investigate:
I want to this but i don't know what to do, the only functions it seems to be useful is "DEC.TO.HEX".
This is the problem, i have in one cell this text:
1234
And in the next cell i want the hexadecimal value of each character, the expected result would be:
31323334
Each character must be represented by two hexadecimal characters. I don't have an idea how to solve this in excel avoiding make a coded program.
Regards!
Edit: Hexadecimal conversion
Text value Ascii Value (Dec) Hexadecimal Value
1 49 31
2 50 32
3 51 33
4 52 34
Please try:
=DEC2HEX(CODE(MID(A1,1,1)))&DEC2HEX(CODE(MID(A1,2,1)))&DEC2HEX(CODE(MID(A1,3,1)))&DEC2HEX(CODE(MID(A1,4,1)))
In your version you might need the .s in the function (and perhaps ;s rather than ,s).
DEC2HEX may be of assistance. Use, as follows:
=DEC2HEX(A3)
First split 1234 to 1 2 3 4 by using MID(), then use Code() for each character, and then again concentate. Below is the formula, Y21 is the cell in which 1234 is written
=CONCATENATE(CODE(MID(Y21,1,1)),CODE(MID(Y21,2,1)),CODE(MID(Y21,3,1)),CODE(MID(Y21,4,1)))
1234 >> 49505152
Basically I'm looking to move a column for one position to another.
561 DISK_GROUP_003 0 545 1
561 Disk_Group_iS 95 84144 80210
561 DISK_GROUP_iS 99 26335 26304
1415 t1_200ea 93 8804 8203
1415 t2_30010k 35 59846 21121
1415 t3_1tb72k 19 184941 36590
1415 t3_3tb72k 86 258635 224328
5018 t1_200ea 98 9905 9802
5018 t2_30015k 89 39987 35986
5018 t2_60015k 67 59984 40700
5018 t3_1tb72k 89 87567 78807
5018 t3_2tb72k 84 94412 79620
I need to move the 3rd column to the end at the right.
This is what I have tried so far:
Sub moveColumn()
With ActiveSheet
Excel.Columns(3).Cut
Excel.Columns(6).PasteSpecial
End With
End Sub
But this method doesn't work as it gets a runtime error '1004'.
Any help would be much appreciated.
For those wondering, it's possible to do this without replacing the contents of the destination column.
For example, to cut column B and insert it to the left of column F, you can use
Columns("B").Cut
Columns("F").Insert Shift:=xlToRight
You can also replace the named column headers with column indices, to taste (so Columns("B") becomes Columns(2))
Pastespecial doesn't work with Cut. You can do this:
Columns(3).Cut Range("F1")
Columns(3).Delete Shift:=xlToLeft 'if you want to delete the empty column
The problem with the other answers given is that the cut/paste technique uses the clipboard—overwriting whatever is in it, and making it impossible for the program to operate correctly if another program that also uses the clipboard is running (such as another instance of the same VBA project).
Instead, do this:
Application.CutCopyMode = False ' don't want an existing operation to interfere
Columns("F").Insert XlDirection.xlToRight
Columns("F").Value = Columns("B").Value ' this would be one greater if to the right of F
Columns("B").Delete
Just note that if there are references to the existing column, they will break and not be updated.
I'm looking for the positions in a string where a specified substring occurs.
E.g, looking for substring "green" in the the string "green eggs and ham" should return me 1, but from "green eggs and green ham" would return me 1 and 14.
How should I do this?
Edit 1: Changed the wording so position starts at 1, not 0.
Edit 2: I can find the first instance as WS-POINTER in the following snippet:
MOVE 1 TO WS-POINTER
UNSTRING WS-STRING(1:WS-STRING-LEN)
DELIMITED BY LT-MY-DELIMITER
INTO WS-STRING-GARBAGE
WITH POINTER WS-POINTER
END-UNSTRING
AFAIK COBOL does not have a statement to find the position of a string within a string, so that needs to be done manually. However, COBOL does have a statement that counts the occurrences of a string within a string:
INSPECT string TALLYING counter FOR ALL search-string
Here is an example program that works in OpenCOBOL (see OpenCobol.org):
IDENTIFICATION DIVISION.
PROGRAM-ID. OCCURRENCES.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
DATA DIVISION.
FILE SECTION.
WORKING-STORAGE SECTION.
01 TEST-STRING-1 PIC X(30)
VALUE 'green eggs and ham'.
01 TEST-STRING-2 PIC X(30)
VALUE 'green eggs and green ham'.
01 TEST-STRING PIC X(30).
01 SEARCH-STRING PIC X(05)
VALUE 'green'.
01 MATCH-COUNT PIC 9.
01 SEARCH-INDEX PIC 99.
01 MATCH-POSITIONS.
05 MATCH-POS PIC 99 OCCURS 9 TIMES.
PROCEDURE DIVISION.
MAIN.
MOVE TEST-STRING-1 TO TEST-STRING
PERFORM FIND-MATCHES
MOVE TEST-STRING-2 TO TEST-STRING
PERFORM FIND-MATCHES
STOP RUN
.
FIND-MATCHES.
MOVE ZERO TO MATCH-COUNT
INSPECT TEST-STRING TALLYING MATCH-COUNT
FOR ALL SEARCH-STRING.
DISPLAY 'FOUND ' MATCH-COUNT ' OCCURRENCE(S) OF '
SEARCH-STRING ' IN:'
DISPLAY TEST-STRING
DISPLAY 'MATCHES FOUND AT POSITIONS: ' WITH NO ADVANCING
PERFORM VARYING SEARCH-INDEX FROM 1 BY 1
UNTIL SEARCH-INDEX = 30
IF TEST-STRING (SEARCH-INDEX:5) = SEARCH-STRING
DISPLAY SEARCH-INDEX ' ' WITH NO ADVANCING
END-PERFORM
DISPLAY ' '
DISPLAY ' '
.
You could use QCLSCAN on IBM i
77 QCLSCAN-SRCHLEN PIC S9(3) COMP-3.
77 QCLSCAN-STARTPOS PIC S9(3) COMP-3.
77 QCLSCAN-PATLEN PIC S9(3) COMP-3.
77 QCLSCAN-XLATE PIC X(01) VALUE "0".
77 QCLSCAN-TRIM PIC X(01) VALUE "0".
77 QCLSCAN-WILDCARD PIC X(01) VALUE LOW-VALUES.
77 QCLSCAN-FOUNDPOS PIC S9(3) COMP-3.
...
...
MOVE LENGTH OF WRK-ACCT-NBR TO QCLSCAN-SRCHLEN
MOVE 1 TO QCLSCAN-STARTPOS
MOVE 9 TO QCLSCAN-PATLEN
MOVE "0" TO QCLSCAN-XLATE
MOVE "0" TO QCLSCAN-TRIM
MOVE "?" TO QCLSCAN-WILDCARD
CALL "QCLSCAN" USING WRK-ACCT-NBR
QCLSCAN-SRCHLEN
QCLSCAN-STARTPOS
EMPLOYEE-SSN-9X
QCLSCAN-PATLEN
QCLSCAN-XLATE
QCLSCAN-TRIM
QCLSCAN-WILDCARD
QCLSCAN-FOUNDPOS
IF QCLSCAN-FOUNDPOS > ZERO
* Found data in position QCLSCAN-FOUNDPOS
ELSE
* Found no match
END-IF
MOVE 1 TO WS-POINTER
UNSTRING WS-STRING(1:WS-STRING-LEN)
DELIMITED BY LT-MY-DELIMITER
INTO WS-STRING-GARBAGE
WITH POINTER WS-POINTER
END-UNSTRING
You ask about how to use the above for subsequent strings.
It is possible to use UNSTRING in two ways to get the counts you want. Either by having multiple receiving fields and COUNT-IN or by using multiple executions of UNSTRING using the POINTER value from the previous UNSTRING each time.
You need to account for the length of the delimiter. However, you will end up with "non-intuitive" code which will have to be "understood" each time someone picks up the program with it in.
Instead, it is a simple task with "substring" processing with either OCCURS DEPENDING ON or reference-modification (the method in the accepted answer).
You must make sure you don't "go beyond the end of the field" by ending the search when count + length-of-delimiter = max-length-of-string-to-search.