How To Cause Click Events When Numbers Are Input In Visual Basic 6 - textbox

I was wondering how I could cause a click event in Visual Basic 6, When a number is input into a text box. I am creating a currency converter and instead of having to click a button to calculate the answer, I would like it so when you input a number, It automatically calculates it, Without the need of clicking anything. There would be two Textboxes, One for input and one for output, I would like it so that when a number is input into the first textbox, It would be calculated and the answer automatically output into the second textbox, Without clicking anything. Thanks :)

You have to use Change event in the input textbox. A sample code follows:
Private Sub Text1_Change()
' get characters from textbox
Dim text As String
text = Text1.text
' if we have a number
If IsNumeric(text) Then
' convert characters to numbers
Dim inputNumber As Double
inputNumber = text
' calculate
Dim answer As Double
answer = calculate(inputNumber)
End If
End Sub
Private Function calculate(number As Double)
' -----------------------------------
' Your calculation here
' -----------------------------------
End Function

Related

Lua pattern -- how can I get this to work?

I have a text file to process, with some example content as follows:
[FCT-FCTVALUEXXXX-IA]
Name=value
Label = value
Zero or more lines of text
Abbr=
Zero or more lines of text
Field A=1
Field B=0
Zero or more lines of text
Hidden=N
[Text-FCT-FCTVALUEXXXX-IA-Note]
One or more note lines
[FCT-FCT-FCTVALUEZ-IE-DETAIL]
Zero or more lines of text
[FCT-FCT-FCTVALUEQ-IA-DETAIL]
Zero or more lines of text
[FCT-_FCTVALUEY-IA]
Name=value
Zero or more lines of text
Label=value
Zero or more lines of text
Field A=1
Abbr=value
Field A=1
Zero or more lines of text
Hidden=N
I need to find sections like this:
[FCT-FCTVALUEXXXX-IA]
Name=value
Label = value
Zero or more lines of text
Abbr=
Zero or more lines of text
Field A=1
Field B=0
Zero or more lines of text
Hidden=N
and extract FCT-FCTVALUEXXXX-AA, Name, Label, Abbr, Field A and B and Hidden, and then find a corresponding section (if it exists):
[Text-FCT-FCTVALUEXXXX-IA-Note]
One or more note lines
end extract the Note lines as a single string.
I don't care about the sections
[FCT-FCT-FCTVALUEZ-IE-DETAIL]
Zero or more lines of text
All three sorts of sections can appear anywhere in the file, including right at the end, and there's no predictable relationship in position between the sections.
The order of Abbr and Fields A and B cannot be guaranteed but they always appear after Name and Label and before Hidden.
What I have so far:
strParse = "(%[FCT%-.-%-)([IF])([EA])%]%c+Name=(.-)%c.-Label=(.-)%c(.-)Hidden=(%a)%c" --cant pull everything out at once because the order of some fields is not predictable
for id, rt, ft, name, label, detail, hidden in strFacts:gmatch(strParse) do
--extract details
abbr=detail:match("Abbr=(.-)%c") --may be blank
if abbr == nil then abbr = "" end
FieldA = detail:match("Field A=(%d)")
FieldB = detail:match("Field B=(%d)")
--need to sanitise id which could have a bunch of extraneous material tacked on the front and use it to get the Note
ident=id:match(".*(%[FCT%-.-%-$)")..rt..ft
Note = ParseAutonote(ident) --this is a function to parse the note which I've yet to test so a dummy function returns ""
tblResults[name]={ident, rt, ft, name, label, abbr, FieldA, FieldB, hidden, note}
end
Most of it works OK (after many hours of working on it), but the piece that isn't working is:
(".*(%[FCT%-.-%-$)")
which is supposed to pull out the final occurrence of FCT-sometext-
in the string id
My logic: anchor the search to the end of the string and capture the shortest possible string beginning with "[FCT-" and ending with "-" at the end of the string.
Given a value of either "[FCT-_ABCD-PDQR-" or
"[FCT-XYZ-DETAIL]lines of text[FCT-_ABCD-PDQR-" it returns nil when I want it to return "FCT-_ABCD-PDQR-". (Note ABCD, PDQR etc can be any length of text containing Alpha, - and _).
As you discovered yourself (".*(%[FCT%-.-%-)$") works the way you want,
where (".*(%[FCT%-.-%-$)") does not. $ and ^ are anchors and must come at the end or beginning of the pattern, they can not appear inside a capture closure.
When the anchor characters appear anywhere else in the pattern they will be part of the string you are looking for, excluding cases where ^ is used in a set to exclude chars i.e.: excluding upper-case chars [^A-Z]
Here are examples of the pattern matching using the an example string and the pattern from your question.
print(string.match("[FCT-_ABCD-PDQR-", (".*(%[FCT%-.-%-$)"))) -- initial pattern
> nil
print(string.match("[FCT-_ABCD-PDQR-$", (".*(%[FCT%-.-%-$)"))) -- $ added to end of string
> [FCT-_ABCD-PDQR-$
print(string.match("[FCT-_ABCD-PDQR-", (".*(%[FCT%-.-%-)$"))) -- $ moved to end of pattern
> [FCT-_ABCD-PDQR-

Update Word 2013 SEQ fields

I'm writing a VBA macro to update ONLY SEQ fields in Word 2013 documents. I designed it to use GoTo to visit each SEQ field one at a time from start to end of the document (NOT Update All) to ensure that I skip other field types. I'm struggling to make it loop for each SEQ field until the end of the document is reached. I want it to work in any document, regardless of bookmarks or other end markers.
Here's the code I have so far (With comments):
ActiveWindow.View.FieldShading = wdFieldShadingAlways
'go to top of document
Selection.HomeKey Unit:=wdStory
'Go To the first SEQ field
Selection.GoTo What:=wdGoToField, Which:=wdGoToNext, Count:=1, Name:="SEQ"
' Selection.Find.ClearFormatting
'as long as there are more field codes, update this one and go to the next one
Do While Selection.GoToNext.wdGoToField = True
Selection.Fields.Update
Loop
It's a bit late, but your question came up when I was looking for the same answer. :-)
For flexibility, the actual work is done as a function, where the field code is received as a string. That way I can call the function with any desired field code, not necessarily a specific SEQ or any field code at all.
Function UpdateSpecificFields(MyFieldCode As String)
Dim MyField As Field
For Each MyField In ActiveDocument.Fields
' Debug.Print """" & MyField.Code & """" & MyField.Result
If InStr(1, MyField.Code, MyFieldCode) <> 0 Then
MyField.Update
End If
Next MyField
End Function
We're looping through all the fields within the active document. You could include a test of whether MyField.Type = wdFieldSequence to reduce the unnecessary work.
The InStr is there in case of odd spacing; sometimes the field creator might include an extra space before or after the code itself, so I didn't want to be too literal. (I suppose there should have been a trim() to get rid of said spaces but I was getting a little lazy.)
Usage: Call the function from a sub.
Sub UpdateSEQQs()
UpdateSpecificFields ("SEQ Qs")
End Sub
I have a SEQ called Qs, so you can see how it was called above. Hope this helps someone!

Rails: Currency to Number

I have some forms on my site where after a user enters currency values those inputs are put into a calculator.
The input needs to be either floats or integers but I want it so that if they enter '$200,000' or '200000' it will both result in '200000.0' after clicking submit. (sort of the opposite of number_to_currency)
I was thinking something like
text = text.gsub(/[$,]/, '').to_f
or better yet take out all non digit characters but this will result in an unintentional zero in the output.
I also would like to format the result in the view so that if the resulting float has nothing after the decimal eg 200.00 then it will round up to 200. Otherwise it will round to 2 decimal place
Most preferably I would like it to work like the presence validator before the form actually submits.
What's the best way to go about implementing this? I'm thinking there is something obvious I've missed.
For the second part, you could do this:
# after converting text to a float
text.modulo(1) == 0 ? text.to_i : sprintf("%.2f", text)
For example, if text = 200000.0, we get 200000 using the above.
On the other hand, if text = 200000.1, we get 200000.10 using the above.

Excel parse cell value

I have placed the following in cell A1:
"a lot of text marker: xxx some more text"
I would like to copy the xxx value into cell A2.
Any suggestions on how this could be done?
Thanks
=MID(A1, FIND("marker:",A1) + LEN("marker:"), 4)
I am assuming that the xxx (per your example) is 3 characters long and a space is present between "marker:" and "xxx".
Just my two cents. Find() is case sensitive so if the text in A1 is
"a lot of text Marker: xxx some more text"
Then Find will give you an error.
You can use Search() in lieu of FIND()
=MID(A1, SEARCH("marker: ",A1) + LEN("marker: "), 3)
Also depending upon your regional settings you might have to use ";" instead of ","
If you wanted a VBA solution, this worked for me using your sample input:
Function GetValue(rng As Excel.Range) As String
Dim tempValue As String
Dim arrValues() As String
' get value from source range
tempValue = rng.value
' split by ":" character
arrValues = Split(tempValue, ":")
' split by spaces and take the second array element
' because there is a space between ":" and "xxx"
GetXXXValue = Trim$(Split(arrValues(1), " ")(1))
End Function
To use, put this code into the sheet module (see Where do I paste the code that I want to use in my workbook for placement assistance) and then put the following into cell A2:
=GetValue(A1)

Getting around the Max String size in a vba function?

The max number of characters you can use in string in a vba function is 255.
I am trying to run this function
Var1= 1
Var2= 2
.
.
.
Var256 =256
RunMacros= "'Tims_pet_Robot """ & Var1 & """ , """ & Var2 & """ , """ ... """ & Var256 """ '"
Runat=TimeValue("15:00:00")
Application.OnTime EarliestTime:=Runat, Procedure:=RunMacros & RunMacros2 ', schedule:=True
It runs a procedure at a certain time and passes a bunch of variables to it. but the string is too long.
Update:
Regrettably I am sure it is not the watch window.
Also, it isn't really the max size of a string that I'm dealing with. It's the max size of
a string in a vba function.
For example this function works.
Sub test()
Dim RunAt As Date
Dim RunWhat As String
RunAt = Now + 0.00001
RunWhat = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" & _
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" & _
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 'that makes 254 'a''s
Application.OnTime EarliestTime:=RunAt, Procedure:="'" & RunWhat & " 12'"
End Sub
Sub aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(m As Integer)
MsgBox ("it works!" & m)
End Sub
But if you change the 12 to 123 it breaks
Example
Sub test2()
Dim RunAt As Date
Dim RunWhat As String
RunAt = Now + 0.00001
RunWhat = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" & _
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" & _
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 'that makes 254 'a''s
Application.OnTime EarliestTime:=RunAt, Procedure:="'" & RunWhat & " 123'"
End Sub
Sub aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(m As Integer)
MsgBox ("it works!" & m)
End Sub
This code does not work, I'm pretty sure it's because a vba function cannot handle a string with more than 255 chars.
Even if you're in Excel and call a function and give it a string longer that 255 chars it doesn't work.
Try in cell A1 =vlookup("really long string", A1:Z10, 1) and then put the really long string somewhere in that range. The vlookup will fail (not fail to find it, but you won't actually be able to do it)
Also I am aware that there is a max length to a sub name, I'm just under it. Sorry that it look so ugly.
Update 2: so I just ended up printing the variable to a sheet and getting the function called by ontime to read them off the sheet. :(
I may have missed something here, but why can't you just declare your string with the desired size? For example, in my VBA code I often use something like:
Dim AString As String * 1024
which provides for a 1k string. Obviously, you can use whatever declaration you like within the larger limits of Excel and available memory etc.
This may be a little inefficient in some cases, and you will probably wish to use Trim(AString) like constructs to obviate any superfluous trailing blanks. Still, it easily exceeds 256 chars.
This works and shows more than 255 characters in the message box.
Sub TestStrLength()
Dim s As String
Dim i As Integer
s = ""
For i = 1 To 500
s = s & "1234567890"
Next i
MsgBox s
End Sub
The message box truncates the string to 1023 characters, but the string itself can be very large.
I would also recommend that instead of using fixed variables names with numbers (e.g. Var1, Var2, Var3, ... Var255) that you use an array. This is much shorter declaration and easier to use - loops.
Here's an example:
Sub StrArray()
Dim var(256) As Integer
Dim i As Integer
Dim s As String
For i = 1 To 256
var(i) = i
Next i
s = "Tims_pet_Robot"
For i = 1 To 256
s = s & " """ & var(i) & """"
Next i
SecondSub (s)
End Sub
Sub SecondSub(s As String)
MsgBox "String length = " & Len(s)
End Sub
Updated this to show that a string can be longer than 255 characters and used in a subroutine/function as a parameter that way. This shows that the string length is 1443 characters. The actual limit in VBA is 2GB per string.
Perhaps there is instead a problem with the API that you are using and that has a limit to the string (such as a fixed length string). The issue is not with VBA itself.
Ok, I see the problem is specifically with the Application.OnTime method itself. It is behaving like Excel functions in that they only accept strings that are up to 255 characters in length. VBA procedures and functions though do not have this limit as I have shown. Perhaps then this limit is imposed for any built-in Excel object method.
Update:
changed ...longer than 256 characters... to ...longer than 255 characters...
Are you sure? This forum thread suggests it might be your watch window. Try outputting the string to a MsgBox, which can display a maximum of 1024 characters:
MsgBox RunMacros
This test shows that the string in VBA can be at least 10^8 characters long. But if you change it to 10^9 you will fail.
Sub TestForStringLengthVBA()
Dim text As String
text = Space(10 ^ 8) & "Hello world"
Debug.Print Len(text)
text = Right(text, 5)
Debug.Print text
End Sub
So do not be mislead by Intermediate window editor or MsgBox output.
Couldn't you just have another sub that acts as a caller using module level variable(s) for the arguments you want to pass. For example...
Option Explicit
Public strMsg As String
Sub Scheduler()
strMsg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
Application.OnTime Now + TimeValue("00:00:01"), "'Caller'"
End Sub
Sub Caller()
Call aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa("It Works! " & strMsg)
End Sub
Sub aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(strMessage As String)
MsgBox strMessage
End Sub
Excel only shows 255 characters but in fact if more than 255 characters are saved, to see the complete string, consult it in the immediate window
Press Crl + G and type ?RunWhat in the immediate window and press Enter
One of the main causes of this problem that I’ve run into is the fact that the entire procedure-plus-arguments string is limited to 255 characters, including the procedure's containing Excel file specification (automatically added by Excel), which is aggravated by Excel’s brain-dead default specification of the file's full-path\name. So, if you have very deep folder structures (like I do) combined with long-ish, descriptive file names and descriptive folder names (like I often use), then that factor can be a frequent problem when using OnTime.
WORKAROUND: I always (!) explicitly include the containing workbook’s name, which apparently alleviates Excel from having to automatically do so (in its nonsensical manner):
Sub CallOnTime()
Application.OnTime Now + TimeSerial(0, 0, 1), _
"'" & ThisWorkbook.Name & "'!'TargetMacro 37,""Some really long String parameter…""'"
End Sub
Sub TargetMacro(I As Integer, S As String)
MsgBox "I=" & I & ", S=" & S
End Sub
That buys me a lot of string-length real estate to use for the called procedure's arguments.
IMPORTANT: note the inclusion and position of the single-quoted bang delimiter ('!') in the above example.
My guess is that the original designer chose to include the full file-path along with the procedure's containing file name to avoid identification ambiguity with other workbooks running under the same instance of the Excel application. But that's a nonsensical rationale because Excel doesn't allow multiple workbooks with the same name to be opened under a single instance, even if they exist under different folder paths (which, of course, they would have to).
Some additional space-saving tips:
If the parameters include a worksheet specification, use its numeric
sheet Index property instead of its name.
Eliminate any space characters around the comma delimiters.

Resources