Assuming each of your strings has this substring, RAPP C/C:, only ONCE in it; AND assuming the 'numeric string' will always be 9 chars in length (as shown in your examples (the last two are identical, by the way), should suffice:
Code:
Private Sub getString(sString)
Dim x As Integer, sArray() As String
x = InStr(1, sString, "RAPP C/C:")
If x > 0 Then
Text1.Text = Mid(Trim(sString), x + 12, 6)
End If
End Sub
Nevermind that we don't know if the string continues after the digits he wants to grab
Last edited by Zvoni; Tomorrow at 31:69 PM.
----------------------------------------------------------------------------------------
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------------------
People call me crazy because i'm jumping out of perfectly fine airplanes.
---------------------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad
'Save the numbers you want to extract in a variable
Dim Xtrct As String
Dim sVal As String
Dim fVal As String
Xtrct = "000009999"
sVal = "RAPP C/C: 000009999"
If sVal = "RAPP C/C: " & Xtrct then
fVal = Xtrct
Else
fVal = "Not found!"
End If
Of course we assume that you know what numbers you want to extract!
Of course we assume that you know what numbers you want to extract!
The whole point is that he DOESN'T know....just wants the right 6 of the numeric value (his example shows 9 chars in that value each time...so have to ASSUME it will always be 9) that follows "RAPP C/C: " (note the space after the colon).
It APPEARS that this "RAPP C/C: " string could be ANYWHERE within any longer string, and we have to ASSUME that there will always be 9 digits immediately following, AND that that string only appears ONCE in any given longer string. IF all these assumptions are correct, the code I posted should work just fine....
But, as common with many threads, it takes many posts to get from the OP what he/she REALLY wants and all the associated parameters along with that. So, probably best to wait to hear what OP says.....
But, as common with many threads, it takes many posts to get from the OP what he/she REALLY wants and all the associated parameters along with that. So, probably best to wait to hear what OP says.....
Indeed! It shouldn't be that difficult to provide all the necessary details regarding the problem.
Sam, if you don't mind, I've taken the liberty of converting your subroutine above into a function to make it easier for the OP to just copy and integrate with his current code.
Code:
Private Function GetLongValue(ByRef sString As String) As Long
Dim x As Long
x = InStr(sString, "RAPP C/C: ")
If x Then GetLongValue = CLng(Mid$(sString, x + 12&, 6&))
End Function
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
Sam, if you don't mind, I've taken the liberty of converting your subroutine above into a function to make it easier for the OP to just copy and integrate with his current code.
I like it....AND, I see I still had my declaration of an array in mine...I was playing with split, but had decided to use instr and mid instead...just forget to remove the declaration.
Someday I'll better understand the use of functions over a sub.
Assuming each of your strings has this substring, RAPP C/C:, only ONCE in it; AND assuming the 'numeric string' will always be 9 chars in length (as shown in your examples (the last two are identical, by the way), should suffice:
Code:
Private Sub getString(sString)
Dim x As Integer, sArray() As String
x = InStr(1, sString, "RAPP C/C:")
If x > 0 Then
Text1.Text = Mid(Trim(sString), x + 12, 6)
End If
End Sub
What if the length of Numbers are not fixed?
i.e. 000000000000999999
or any length
One more thing, What is the use of sArray() As String
Try this function if you are sure with delimiters:
Code:
Public Function TextBetweenWords(ByRef strText$, ByRef strWord1$, ByRef strWord2$) As String
Dim lngPos1&, lngPos2&, lngStart&
lngPos1 = InStrB(strText, strWord1)
If lngPos1 Then
lngStart = lngPos1 + LenB(strWord1)
lngPos2 = InStrB(lngStart, strText, strWord2)
If lngPos2 Then
TextBetweenWords = MidB$(strText, lngStart, (lngPos2 - lngStart))
End If
End If
End Function
Last edited by green.pitch; Jul 20th, 2013 at 02:04 PM.
errrr...that is why I put in my tiny example...."IF" and "ASSUME". BASED SOLELY on the EXAMPLE, my code works...MAYBE, just MAYBE, all the assumptions and ifs are right....but I doubt it....:-).
I only gave that example to give OP an IDEA of what to do....there are so many unknowns....best just to wait now to see if those assumptions were correct...if not, then, obviously, some other code is going to have to do....AND, there are many ways to manipulate strings in VB6 (as you probably know)....let's just wait and see...THEN we can 'throw other ideas' to the OP.
PS-the array declaration was explained in post #10. Obviously not needed as I decided not to use split() in my ex.
I like it....AND, I see I still had my declaration of an array in mine...I was playing with split, but had decided to use instr and mid instead...just forget to remove the declaration.
Someday I'll better understand the use of functions over a sub.
Sam, a function has the ability to return a variable/array, that's the only different I can see.
Thought so....thx, Max.
So, really no 'difference' using a sub with a global variable (unless one wants to keep that global variable, and use a second one (returned from the function))...correct?
Here is an example (hope it not too complicated haha)
VB6 passes variables ByRef as default, but I added ByRef to the sub anyway. (you do not need to add ByRef, as it should already be)
Code:
Private Sub Form_Load()
Dim SubString As String
Dim FuncString As String
Debug.Print ""
Debug.Print "Empty String"
Debug.Print "---------------------"
Debug.Print "SubString: " & SubString
Debug.Print "FuncString: " & FuncString
Debug.Print ""
Debug.Print "Return String"
Debug.Print "---------------------"
ReturnSubString SubString
FuncString = ReturnFuncString
Debug.Print "SubString: " & SubString
Debug.Print "FuncString: " & FuncString
End Sub
Private Sub ReturnSubString(ByRef RetString As String)
RetString = "Sub Sam"
End Sub
Private Function ReturnFuncString() As String
ReturnFuncString = "Function Sam"
End Function
Now change ByRef to ByVal and it will not return the passed variable.
The only difference is you can return a variable using function, while a sub you cannot.
But you can return a passed variable with a Sub or a Function.
I find it easier just to return using a function, less confusing for me anyways.
Whoever said a sub cannot return something? Just use a byref-argument in your sub call.
oh, and a sub has in this case an advantage over a function: you can return more than one result.
ok, admittedly, you could use the same technique with functions. It's the way the win-api works after all
Last edited by Zvoni; Tomorrow at 31:69 PM.
----------------------------------------------------------------------------------------
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------------------
People call me crazy because i'm jumping out of perfectly fine airplanes.
---------------------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad
Max/Z -- good class. Thx. Will play with both techniques more in the future. Was always confused about byRef and byVal...this easiy clears it up 4 me. And who said you can't teach an old dog new tricks?
Whoever said a sub cannot return something? Just use a byref-argument in your sub call.
oh, and a sub has in this case an advantage over a function: you can return more than one result.
ok, admittedly, you could use the same technique with functions. It's the way the win-api works after all
Whoever did not read my post correctly or see the example provided?? It does exactly what you just said (or what I said in the first place).... but in the end you cannot return the sub as a variable. You can returned the passed variables to it.
@Sam
I'm happy it gave you a different point of view, sometimes just a different example makes you understand things better, even if that example was not at it's best.
But you see now what ByVal does and what ByRef does. If you do not want to modify the passed variable (argument/parameter) then you simply use ByVal.
Whoever said a sub cannot return something? Just use a byref-argument in your sub call.
oh, and a sub has in this case an advantage over a function: you can return more than one result.
ok, admittedly, you could use the same technique with functions. It's the way the win-api works after all
Being really picky, a Function Returns a value (which can be multiple values e.g. an array) which can be assigned to a variable in the Calling routine. A Subroutine can modify arguments passed to it ByRef - it doesn't 'return' anything.
Last edited by Doogle; Jul 21st, 2013 at 01:51 AM.
A function 'returns' a value by writing the result into a variable, which is just an adress in memory
a sub modifies a byref-argument, which is an adress in memory, too.
i really don't see a difference....
Last edited by Zvoni; Tomorrow at 31:69 PM.
----------------------------------------------------------------------------------------
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------------------
People call me crazy because i'm jumping out of perfectly fine airplanes.
---------------------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad
Maybe he ran away, when he saw that yet again one of his threads has been turned into techno-babble of philosophical proportions
Last edited by Zvoni; Tomorrow at 31:69 PM.
----------------------------------------------------------------------------------------
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------------------
People call me crazy because i'm jumping out of perfectly fine airplanes.
---------------------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad
A function 'returns' a value by writing the result into a variable, which is just an adress in memory
a sub modifies a byref-argument, which is an adress in memory, too.
i really don't see a difference....
A function does not write into any variable. It returns a value which can be assigned to a variable. A sub can alter a variable directly through a ByRef parameter.
C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter
There's just no reason to use garbage like InputBox. - jmcilhinney
The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber
I think I'd use 'Brute Force' (with a little ignorance):
Code:
Option Explicit
Private Function ReturnDigits(strData As String) As String
'
' Function searches strData backwards for 6 contiguous numeric values
' if 6 are found it returns them.
' Otherwise an appropriate message is output and vbNullString is returned
'
Dim lngI As Long
Dim intI As Integer
Dim binGotNumeric As Boolean
Dim binFail As Boolean
lngI = Len(strData)
Do
Do
If Mid$(strData, lngI, 1) >= "0" And Mid$(strData, lngI, 1) <= "9" Then
binGotNumeric = True
Else
lngI = lngI - 1
End If
Loop Until binGotNumeric Or lngI = 0
If lngI <> 0 Then
lngI = lngI - 1
If lngI > 0 Then
Do
If Mid$(strData, lngI, 1) < "0" Or Mid$(strData, lngI, 1) > "9" Then
binGotNumeric = False
Else
lngI = lngI - 1
intI = intI + 1
End If
Loop Until binGotNumeric = False Or intI = 5 Or lngI = 0
If intI = 5 Then
ReturnDigits = Mid$(strData, lngI, 6)
End If
If lngI = 0 Then
MsgBox "6 digits not found"
binFail = True
End If
Else
MsgBox "Only found 1 numeric"
binFail = True
End If
Else
MsgBox "Did not find any Numerics"
binFail = True
End If
lngI = lngI - 1
intI = 0
Loop Until ReturnDigits <> vbNullString Or binFail
End Function
Private Sub Command1_Click()
Dim strA As String
Dim strB As String
Dim strC As String
Dim strData As String
Dim strRecords() As String
Dim lngI As Long
Dim intI As Integer
Dim intFile As Integer
intFile = FreeFile
Open "C:\MyDir\instr_string.txt" For Input As intFile
strData = Input(LOF(intFile), intFile)
Close intFile
strRecords = Split(strData, vbNewLine)
For intI = 0 To UBound(strRecords)
strA = strRecords(intI)
lngI = InStr(strA, "RAPP C/C:")
If lngI Then
strB = Mid$(strA, lngI + 9)
strC = ReturnDigits(strB)
Debug.Print strC
End If
Next intI
End Sub
EDIT: Assumes that a record such as:
Code:
RAPP C/C: 000009999 09009
should return 009999 (i.e. the last 6 contiguous digits) as opposed to 909009 (i.e. the last 6 digits) it's a very simple modification to the Function if that's not the case
Last edited by Doogle; Jul 23rd, 2013 at 02:45 AM.
Reason: Changed original code to use OP's example file
So i was actually quite close with my guess that the string continues after the digits he wants to grab
Last edited by Zvoni; Tomorrow at 31:69 PM.
----------------------------------------------------------------------------------------
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------------------
People call me crazy because i'm jumping out of perfectly fine airplanes.
---------------------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad
Here is my take on it. I added more code than is needed for readability
Code:
Option Explicit
Private Sub Command1_Click()
Dim arrInput(6) As String
Dim strInput As String
arrInput(0) = " 444455 RAPP C/C: 000009999"
arrInput(1) = "or"
arrInput(2) = " 44444 RAPP C/C: 000009999 0900909"
arrInput(3) = "or"
arrInput(4) = " RAPP C/C: 000009999 yuiuiiiuiui"
arrInput(5) = ""
arrInput(6) = "ecc..."
strInput = Join(arrInput, vbCrLf)
MsgBox GetNum(strInput)
End Sub
Private Function GetNum(ByVal strInput As String) As String
Dim arr() As String
Dim strRet As String
' Remove line breaks that may cause problems
strInput = Replace(strInput, vbCr, " ")
strInput = Replace(strInput, vbLf, " ")
arr = Split(strInput, "RAPP C/C: ")
' if there is more than one element the split was successful
If UBound(arr) > 0 Then
' Grab the second element. This should be the start of your number
strRet = arr(1)
' Split on the space so you can isolate the number you want
arr = Split(strRet, " ")
' The first element should now contain just the number that you need
strRet = arr(0)
' Grab the right 6 characters from the number
strRet = Right(strRet, 6)
' Return the results
GetNum = strRet
Else
GetNum = "Not Found"
End If
End Function
And here is the ugly abbreviated form
Code:
Private Function GetNum(ByVal strInput As String) As String
Dim arr() As String
' Remove line breaks that may cause problems
strInput = Replace(Replace(strInput, vbCr, " "), vbLf, " ")
arr = Split(strInput, "RAPP C/C: ")
' if there is more than one element the split was successful
If UBound(arr) > 0 Then
GetNum = Right(Split(arr(1), " ")(0), 6)
Else
GetNum = "Not Found"
End If
End Function
I can have this strings:
RAPP C/C: 000009999 |
or
RAPP C/C: 000009999
or
RAPP C/C: 000009999
ecc...
i ned to intercept the string RAPP C/C: in whatever position and get always the right 6 digit from numeric string.
in this case i need to get 009999
what about this :
Code:
Dim lenText as integer
dim Numtext as string
lenText = len(txtString)
Do While lenText > 0
if isnumeric(Mid(txtString,lenText,1)) then 'check if the string is numeric or not
if len(Numtext) < 6 Then Numtext = Numtext & Mid(txtString,lenText,1) Else Exit Do
end if
lenText = lenText - 1
Loop
Here is my take on it. I added more code than is needed for readability
Call me picky but the code only returns the first number. Suspect you need a loop to go through all the array elements which may get a little tricky where you've got something like
Code:
RAPP C/C: 000009999 0900909
lberally sprinkled around in the Input. (Makes it difficult to identify the element number you actually want (IMHO))
Call me picky but the code only returns the first number. Suspect you need a loop to go through all the array elements which may get a little tricky where you've got something like
Code:
RAPP C/C: 000009999 0900909
lberally sprinkled around in the Input. (Makes it difficult to identify the element number you actually want (IMHO))
Not difficult at all.
Code:
Private Sub Command1_Click()
Dim arrInput(6) As String
Dim strInput As String
Dim arr() As String
Dim i As Integer
arrInput(0) = " 444455 RAPP C/C: 000009999"
arrInput(1) = "or"
arrInput(2) = " 44444 RAPP C/C: 000009999 0900909"
arrInput(3) = "or"
arrInput(4) = " RAPP C/C: 000009999 yuiuiiiuiui"
arrInput(5) = ""
arrInput(6) = "ecc..."
strInput = Join(arrInput, vbCrLf)
arr = GetNum(strInput)
For i = 0 To UBound(arr)
Debug.Print arr(i)
Next i
End Sub
Private Function GetNum(ByVal strInput As String) As String()
Dim arrRAPP() As String
Dim arrNum() As String
Dim arrRet() As String
Dim strRet As String
Dim i As Integer
' Remove line breaks that may cause problems
strInput = Replace(strInput, vbCr, " ")
strInput = Replace(strInput, vbLf, " ")
arrRAPP = Split(strInput, "RAPP C/C: ")
' if there is more than one element the split was successful
If UBound(arrRAPP) > 0 Then
For i = 1 To UBound(arrRAPP)
' Grab the second element. This should be the start of your number
strRet = arrRAPP(i)
' Split on the space so you can isolate the number you want
arrNum = Split(strRet, " ")
' The first element should now contain just the number that you need
strRet = arrNum(0)
' Grab the right 6 characters from the number
strRet = Right(strRet, 6)
ReDim Preserve arrRet(i - 1)
arrRet(i - 1) = strRet
Next i
' Return the results
GetNum = arrRet
Else
ReDim arrRet(0)
arrRet(0) = "Not Found"
GetNum = arrRet
End If
End Function
The problem is that I believe OP would expect 009999, 900909 and 009999 from the Input you're using rather than 009999, 009999, 009999 which is what's being output.
I didn't get that from the post. The way I read it was they wanted the last 6 digits of the number following RAPP C/C:. If they need something further down the string then what I posted would certainly need some work.
The problem is that I believe OP would expect 009999, 900909 and 009999 from the Input you're using rather than 009999, 009999, 009999 which is what's being output.
No, I don't think so...hard to tell unless OP explains WHAT he wants to get. It just appears that OP would want (to me) to get is 009999, 009999 and 009999. AND, I STILL am not sure if that 'text file' is nothing more than three separate strings he is giving as an example, or if that file is an actual file (with the 'or' lines in it.
Waiting to see what OP says about all comments......