VBScript newbie, GetObject 424 Object Required when connecting to application - vbscript

I am trying to connect to an open application and send command to one of it's DLL functions. Here is the code- the error happens on the the GetObject. What am I doing wrong?
Dim oOL
Dim lcCmd
lcCmd = "'QQWOMOD.TWOAuto', '100',False"
MsgBox lcCmd
On Error Resume Next
'The Next stmt is commented out, but gives the same error as the one that follows it
'Set oOL = GetObject("C:\Program Files (x86)\Component Control\Quantum Control\Quantum.exe", "Quantum.SysMod")
Set oOL = GetObject("Quantum.SysMod")
If oOL is Nothing Then
MsgBox "1- " + Err.Description
MsgBox "1- " + Err.number
End If
MsgBox ("2")
oOL.InspectWO(lcCmd)
MsgBox("3")

A suggestion: comment this line and run the program again.
On Error Resume Next
This line is not allowing you to understand the error because the program will go ahead even though the error is raised.

Welcome to Stack Overflow. I'm still amazed by the number of people who start programming using ancient VBScript, but let's see this through. :)
The first thing you need to do is avoid using On Error Resume Next wherever possible, since this will mask the true cause of your errors. The error you report, Object Required is because oOL has not been set at all due to an error with the line above. If I take your example and allow errors, we'll see that it's complaining about a syntax error stemming from the call to GetObject. I believe you meant to use CreateObject?
Assuming that's the case, you'll have to run it again and see if it works. If not, and you get an error like "ActiveX component can't create object" it means you don't have the necessary DLL installed for Quantum SysMod. You should look at the software's documentation to see about registering it. You can also reference the regsvr32 page.
Again, if you have any other development tools available to you that can load the required component such as, C# or even VB.Net, then you should really try using those instead. VBScript is a terrible language.

Related

Cannot convert Group Description to String Variable

I have the following code:
Set objHoldGroup = GetObject("LDAP://" & objGroup)
strGroupDesc = (objHoldGroup.Description)
WScript.Echo(strGroupDesc)
The variable strGroupDesc returns nothing when echoed. I can output the description directly but I need it for further processing. Thoughts?
Explanation: Apparently your script sets Option Explicit (good), which you didn't tell us about (bad). This option makes defining variables before you can use them mandatory (good). Normally that would raise an "undefined variable" error, though. Since that doesn't seem to happen with your code, you seem to also have an On Error Resume Next somewhere in your code (very bad), which, again, you chose to keep quiet about (bad).
Next time please don't omit parts of your code that are vital for troubleshooting the problem. And don't use On Error Resume Next.
Issue found: I forgot to Dim strGroupDesc.

compile error: method or data member not found in vb6

Hi all I am a php developer but since working in an organisation I got a work on a vb6 project.
The software is quite old let say atleast 10 year and I don't know vb6 at all. But still I manage to solve some errors but now I stuck on and I didn't get any solution. I have got this error when compiling the project, highlighting this code.
with .Panels(6) = selected.
Public Sub StatusBarDateTime()
'' FrmMain.Stb1.Panels(5) = Time
FrmMain.Stb1.Panels(6) = Format(Date, "dd-mmm-yyyy")
End Sub
and when I delete this line on code it show another error that
Compile error:
Sub or Function not defined
highlighting this line of codes
Private Sub MDIForm_Load()
StatusBarDateTime
End Sub
I assumed that it is declaring the function. so I delete this function also.
Now after deleting this when I compiled againg I got this error saying that
Run time error'481'
Invalid picture
and when I click on debug it shows this line of code
Private Sub Form_Load()
FrmMain.Show
Dim strUser As String
Call Center_Align(FrmLogin)
OpenConnection
strUser = "select * from TMUser order by login_name"
rsUser.Open strUser, conpgdhm, adOpenKeyset, adLockOptimistic
Set CmbUserID = rsUser
CmbUserID = "login_name"
CmbUserID = "login_id"
End Sub
highlihting Set CmbUserID = rsUser line. and now I got nothing.
I don't know how many error may I get after resolving this but that is the next part.
First I have to solve this. I have no idea how to resolve this.
I am banging my head around for two days now, If someone can help me please.
Thanks in advance.
Those were helpful....
The reason it's stopping there is because you are attempting to assign a datareader (or whatever object type rsUser is) as the value to a string or int type (CmbUserID)
You are trying to fit a whole bag of rectangles into a round whole. This is in reference to your latest error only. Based on what I see here, you lack the experience in VB6 to continue without some assistance. I suggest a consultant.
Hope this helps.

Execute code if application crashes?

small question, in Visual Basic 6.0 (VB6)
Assuming I missed a possible situation and the user did something and did not expect, then he gets an error that crashes my application. Is there an event I can work with that will execute a certain code if that happens ?
Tried Form_Terminate \ Unload \ Query_Unload, not much luck there.
Crash:
AKA Run-Time Error.
You can add an On Error check at any level, including your Sub Main. Any errors that are not caught by an error check at that functions level will rise through the call stack to the main/initial method where you could there catch them.
You could then gracefully display the error (so you or your users are aware of it) and then resume whatever method is best at that point. And, remember, you can do this at several different strategic levels and locations.
If the errors occur in an event procedure, then these won't be trapped in Sub Main() so you will also need to catch them there.
Any errors that rise to the top of the stack, either out of Sub Main() or an event procedure will be caught by the runtime and are fatal. Your code will get no notification of this.
You may also be interested in the post Good Patterns For VBA Error Handling.
On the the frequent ways to capture error in VB6, is by using the On Error and the GOTO tags. At the beginning of each Function, you just declare the goto in case of error, and whenever an error arises, the GOTO part will be executed.
Note that the Goto part should go at the end of the method, so as after running the codes, no other piece of code is executed but leave the Function. Check the example below;
Private Function MyMethod()
Dim sMsg As String
On Error Goto ErrHandler
' ...code here...
Exit Function
ErrHandler:
sMsg = "Error #" & Err.Number & ": '" & Err.Description & "' from '" & Err.Source & "'"
GoLogTheError sMsg
End Function

VB6 "Invalid use of property" error where the code seems fine

I am having a very strange problem. First, the code.
Private Function ProcessRecord(ByVal rsDocs As ADODB.Recordset) As Variant
Dim rsTemp As ADODB.Recordset
rsTemp = rsDocs
rsDocs = RemoveDuplicateDocs(rsTemp)
Exit Function
The error is occurring on the second line of the function, where rsTemp is set equal to rsDocs. It's saying: "Compile error: Invalid use of property". I've looked for information on this error elsewhere, and all the reports are cases where people either forgot an equal sign, or incorrectly added the "Set" command to the beginning of the line of code. This error makes no sense to me, because it was compiling fine before, and the changes I've made to this project are not even in the class that throwing the error. The code here is identical to the way it was before. Has anyone ever seen an error like this pop up for what seems to be no good reason? Thanks!
You need to use
set rsTemp = rsDocs
since rsTemp is an object.

Is it possible to retrieve the call stack programmatically in VB6?

When an error occurs in a function, I'd like to know the sequence of events that lead up to it, especially when that function is called from a dozen different places. Is there any way to retrieve the call stack in VB6, or do I have to do it the hard way (e.g., log entries in every function and error handler, etc.)?
You do have to do it the hard way, but it's not really all that hard... Seriously, once you've written the template once, it's a quick copy/paste/modify to match the function name in the Err.Raise statement to the actual function name.
Private Function DoSomething(ByVal Arg as String)
On Error GoTo Handler
Dim ThisVar as String
Dim ThatVar as Long
' Code here to implement DoSomething...
Exit Function
Handler:
Err.Raise Err.Number, , "MiscFunctions.DoSomething: " & Err.Description
End Function
When you have nested calls, this unwinds as each routine hits its Handler and adds its name to the error description. At the top level function, you get a "call stack" showing the list of routines that were called, and the error number and description of the error that actually occurred. It's not perfect, in that you don't get line numbers, but I've found that you don't usually need them to find your way to the problem. (And if you really want line numbers, you can put them in the function and reference them in the Err.Raise statement using the Erl variable. Without line numbers, that just returns 0.)
Also, note that within the function itself, you can raise your own errors with the values of interesting variables in the message like so:
Err.Raise PCLOADLETTER_ERRNUM, , "PC Load Letter error on Printer """ & PrinterName & """"
(The syntax highlighting looks wonky in the preview... I wonder how will it look when posted?)
I'm pretty sure you have to do it the hard way. At a previous job of mine, we had a very elegant error handling process for VB6 with DCOM components. However, it was a lot redundant code that had to be added to every method, so much that we had home-grown tools to insert it all for you.
I can't provide too much insight on its implementation (both because I've forgotten most of it and there's a chance they may consider it a trade secret). One thing that does stand out was that the method name couldn't be derived at run-time so it was added as a string variable (some developers would copy-paste instead of using the tool and it would lead to error stacks that lied...).
HTH
The hard, manual way is pretty much the only way. If you check out this question, someone suggested a tool called MZTools that will do much of the grunt work for you.
As other people said (years ago, I see... but there's so many people still using VB6! :) ), I think it's not possible to programmatically retrieve the Call Stack, unless you use some 3rd-party tool.
But if you need to do that for debugging purposes, you can consider of adding to the called routine an Optional input string variable, were you'll put the caller's name.
Sub MyRoutine
(...) ' Your code here
call DoSomething (Var1, Var2, Var3, "MyRoutine")
' ^
' Present routine's name -----------+
(...) ' Your code here
End Sub
Public DoSomething (DoVar1, DoVar2, DoVar3, Optional Caller as string = "[unknown]")
Debug.Print " DoSomething Routine Called. Caller = " & Caller
... ' (your code here)
End Sub
Not so elegant, maybe, but it worked for me.
Regards,
Max - Italy
Compuware (or was it Numega at the time) DevStudio for Visual Basic 6 used to do this. The way was by adding adding instrumenation to every call that called a very small snippet that added to the code stack. On any error it dumped out that callstack, and then did things like mail or post to a webserver all the debuging information. Adding and removing the instrumentation was a potentially lethal operation (especially back then, when we were using VSS as our source control), but if it worked, it work well.
As Darrel pointed out, you could add something very simlar by using MZTools and setting up a template. It's a lot of working, and is probably more effeort than the reward would be but if you have very difficult to track down bugs, it might help).

Resources