Check full value of a long string in the VB6 IDE - vb6

I have a string 'sSQL' that contains a very long tsql statement. I need to check what its value is while debugging. I usually just use ?sSQL in the immediate window but this is truncating the first half and only giving me the end half.
So is there an alternative way to see the full value using the vb6 sp5 dev environment?

For debugging, Clipboard.Clear: Clipboard.SetText ssql then paste into notepad.

While execution is paused on the breakpoint you could type in the immediate window:
Debug.Print(sSql)
;-)

One way is to use write the string out to a file. You can do this in a single line in the immediate window by using Line continuations, e.g.:
Open "C:\SQL.TXT" For Append As #1: Write #1,sSQL : Close #1
Note: You'll need to change C:\SQL.Txt to a path that you can write to depending on your OS.

If it's that long, save it to a text file. Have a debug method:
sub SaveStringToDebugFile(s as string)
...
end sub
and then call it from the immediate window:
SaveStringToDebugFile sSQL

Erm, the immediate window doesn't truncate (except at 200 lines of 1023 characters). Have you just tried pressing the home key or scrolling left?

Check the length of the "long" string using the Immediate:
?len(sSQL)
4221
then knowing the size you can start getting chunks of string using Mid function:
?Mid(sSQL, 1, 500)
?Mid(sSQL, 500, 1000)
?Mid(sSQL, 1000, 1500)

Related

Scripting Word from vbs

I'm trying to get Word to fill in cells in a table. The script works when run as a macro from within Word, but fails when saved as a .vbs file and double-clicked, or run with wscript. This is a part of it.
set obj = GetObject(,"Word.Application)
With obj
With .Selection
MsgBox .text
If (.Information(wdWithInTable) = True) Then
.Collapse Direction:=wdCollapseStart
tCols = .Tables(1).Columns.Count
tRow = .Information(wdStartOfRangeRowNumber)
tCol = .Information(wdStartOfRangeColumnNumber)
For I = 2 To 5
.Tables(1).Cell(tRow, I).Range.Text = "fred" & Str(I)
Next
` now make new row
For I = 1 To tCols - tCol + 1
.MoveRight unit:=wdCell
Next
End If
End With
End With
I have three problems. First, it won't compile unless I comment out the .Collapse and .MoveRight lines. Second, although the MsgBox .text displays the selected text, I get "out of range" errors if I try to access any .Information property.
I'm sure I'm missing something very simple: I usually write software for Macs, and I'd do this using AppleScript. This is my first attempt at getting anything done under Windows.
VBScript and VBA are different languages.
They are a bit similar, but not very. Moreover, VBScript is not like AppleScript; it doesn't let you easily interface with running programs.
The interfaces you'll get from VBScript can behave subtly differently in VBA and VBScript. However, I think you've got two problems here:
:= is invalid syntax in VBScript; you'll need to find an alternative way of calling the function. Try just using positional arguments.
You've no guarantee that this will open the expected file; there could be another instance of Word that it's interacting with instead.
Since your code is not running within the Word environment it would require a reference to the Word object library in order to use enumeration constants (those things that start with wd).
VBScript, however, cannot work with references, which means the only possibility is to use the long value equivalents of the enumerations. You'll find these in the Word Language References. Simplest to use is probably the Object Browser in Word's VBA Editor. (In Word: Alt+F11 to open the VBA Editor; F2 to start the Object Browser; type in the term in the "Search" box, click on the term, then look in the bottom bar.)
The code in the question uses, for example:
wdWithInTable
wdCollapseStart
wdStartOfRangeRowNumber
wdStartOfRangeColumnNumber
wdCell
The reason you get various kinds of errors depends on where these are used.
Also, VBScript can't used named parameters such as Unit:=. Any parameters must be passed in comma-delimited format, if there's more than one, in the order specified by the method or property. If there are optional parameters you don't want to use these should be left "blank":
MethodName parameter, parameter, , , parameter

ORA-6502 Character string buffer too small error with Execute immediate statement

I get an Oracle error ORA-6502 Character string buffer too small in my code at the statement below
EXECUTE IMMEDIATE 'BEGIN :project_id :=
Activity_API.Get_Project_Id(:activity_seq); END;'
USING OUT project_id_, activity_seq_
project_id_ - this is a local variable in the function
activity_seq_ -- this is an IN parameter to the function.
I don't understand the cause of the error. Besides, the error is not consistently showing up.
Please help me know what am I missing out.
Thanks.
Generally this error means that you have a VARCHAR(N) variable somewhere in your code and you tried to assign VARCHAR(N+x) value to it. It may happens anywhere, say:
size of activity_seq_ is too big for function local variable
size of project_id_ is too small for function result
there is some oversized value used into the function itself
etc.
Sometimes it may happens because of multibyte character set used, say, if value is VARCHAR(N chars) while assignment target is VARCHAR(n bytes). Anyway, you should just debug it. Use PL/SQL Developer or any other tool which can trace stored procedures row by row, run your statement into the test window and see what happens, where and why.

"Compile Error: Only Comments may appear after End Sub, End Function.." Access 2010 VBA

I am creating a form and I have created my first function in the VBA window. The function creates Buttons. After I type anything after the 'End function' I get an error- "Only comments appear after .." What's wrong? Am I putting the function in the wrong area?
Here is my code:
Option Compare Database
Option Explicit
Function MainMenuOptions()
Dim frm As String
frm = "Main"
Dim SCFormB As Control
Dim SCSearchB As Control
Dim SCReportB As Control
Set SCFormB = CreateControl(frm, acOptionButton, , , , 0.5, 0.6, 1.5, 0.55)
Set SCSearchB = CreateControl(frm, acOptionButton, , , , 0.5, 1.5, 1.5, 0.55)
Set SCReportB = CreateControl(frm, acOptionButton, , , , 0.5, 2.4, 1.5, 0.55)
End Function
I have recently had this problem. I'm creating a new Shares/Derivatives trade and management application, and I'm making awesome progress on creating a form, when at one point, I starting getting this error for ALL of the _Click() handlers for the controls on the form. But, it was not happening for an _Enter() handler for one of the fields on the form. There was no extraneous text after any of the 'End' statements - at all! I discovered that, somehow, the incorrect LINE ENDINGS had made their way onto the ends of the 'End' statements.
The Fix: go to the end of each of your 'End' statements, hit DELETE until the next Sub statement comes up to the cursor (i.e., you now have the start of the next procedure on the same line as the previous proc's End statement), then hit ENTER to put the next Sub statement back on it's own line. This will ensure that you have the correct CR/LF (or whatever is required of that editor/compiler) at the ends of each of your event handlers.
Apparently, you have extra code in your module which is outside of a function or sub. In the VBA editor select debug -> compile and it should highlight the offending code which you can remove or revise.
FYI: CreateControl uses twips(one 1440th of an inch) for left, top, width, and height. You may want to multiply the numbers you are using by about 1440.
If you check the Microsoft Office Dev Center for this error message you get the following explanation:
You placed executable code outside a procedure. Any nondeclarative
lines outside a procedure must begin with a comment delimiter (').
Declarative statements must appear before the first procedure
declaration. Comments are ignored when the code executes.
This means that the type of code you can write outside a Sub or Function is limited.
I had this error, and the solution was simple, however VBA's debugger threw me off the scent for a while. I had extra code after "End Sub" that needed deleting (copy and paste error), however rather than highlighting the extra code after the "End Sub" statement, the debugger highlighted the beginning of the Sub procedure, causing me to think that the error was between the opening statement of the highlighted Sub procedure and the "End Sub" ABOVE it, when in fact the error was after the "End Sub" of the highlighted sub procedure, so I needed to look well BELOW the highlighted text. So, in effect, VBA highlighted the beginning of a sub-procedure that was entirely fine, rather than the issue immediately after it.
It's like someone leaving a bag of trash immediately outside your front door so you walk into the trash as soon as you walk through the door, and then you say "Huh, I need to move the trash" while pointing at the door.
I had this issue as well, but I didn't have any code outside of my subs. I was getting the error after Access would generate a piece of code (I was trying to add code for the NoData state of my report). When I put a dummy comment below the End Sub that was having the issue it fixed the issue, at least for the last three compiles I have done.

Embed EXE file in the Excel file

I use:
retVal = Shell("program.EXE " & filename, vbNormalFocus)
To execute a program need for my excel spreadsheet.
Is it possible to embed the EXE file in the excel file itself?
And how would I execute it then?
Ideias:
1 - Some kind of a bin2str function to turn binary to string (so I can store it in the program as a variable and a str2bin (the oposite)
2 - I read something about OLE Control (that you can embed it there), but I really don't know where to start on this one
Here's an outline solution that avoids OLE:
Create a hidden worksheet.
Use a base 64 encoded to convert the exe to text.
Store that text in worksheet cells on the hidden worksheet. Since there is a limit on the number of characters in a cell (32,767) you will need to break the string into chunks.
Obviously you'll need to reverse this procedure when you want to save and execute the exe file.
You can do this by using: Insert > Object and then selecting 'Create from File'.
To add it to your sheet using VBA:
Dim o As OLEObject
Set o = ActiveSheet.OLEObjects.Add(Filename:="C:\program.exe")
Then this is the command to execute program.exe:
o.Verb Verb:=xlPrimary
Not sure how to pass arguments to it, however (e.g. your filename).
Note: Untrusted applications prompt a warning when you run them.

VB6 control iteration: one control gives me an error; which one?

I am trying to loop through all controls in a form:
For Each ctrl in Me.Controls
in order enable/disable the control based on some conditions.
But there is a control on the form that gives an error when I try to access it. What kind of control does that, and how do I find it?
When you get your error and click Debug, is the error on the line setting a control's Enabled property?
If so, add a Debug.Print statement writing out the control's name. Do so on the line before setting the Enabled property.
Here's what I mean:
Dim ctrl As Control
For Each ctrl In Me.Controls
Debug.Print ctrl.Name
ctrl.Enabled = True
Next
The Debug.Print statement will write out to the Immediate Window the name of the control that was last processed in the loop, presumably the one that caused your error.
EDIT
This might work. Put this control in a Panel control and set the Panel's Enabled property to False. If I recall correctly, in VB6 setting a container control's Enabled property to False will also set the container's child controls Enabled to False. If your control's Enabled property really is read-only, I'm curious what would happen.
Try this:
Dim ctr As Control
Dim CtrStatus Boolean
CtrStatus = False
For Each ctr In Me.Controls
If (SSTab.hwnd = GetParent(ctr.hwnd)) Then
Call CallByName(ctr, "Enabled", VbLet, CtrStatus)
else
ctr.Enabled = CtrStatus
End If
Next
Another approach is as follows, that also works at runtime (as opposed to just in the IDE):
private sub SetEnabled()
on error goto errHandle
Dim ctrl As Control
For Each ctrl In Me.Controls
ctrl.Enabled = True
Next
exitPoint:
exit sub
errHandle:
MsgBox "Error " & err.Description & " with Control " & ctrl.Name
resume exitPoint
end sub
Suppress the error reports before the loop and then set it back to standard error handling:
On Error Resume Next
For Each ctrl In Me.Controls
ctrl.Enabled = lIsEnabled
Next
On Error GoTo 0
OR name your controls with a standard prefix/suffix that you can check by name and skip in the loop.
For Each ctrl In Me.Controls
If Left(ctrl.Name, 3) = "sst" Then
ctrl.Enabled = lIsEnabled
End If
Next
Tosa: from your comment on AngryHacker's answer, I think you are checking the container incorrectly.
Your code is like this
' BAD CODE '
If ctrl.Container = fraMovies Then
For me that gives error 450 Wrong number of arguments or invalid property assignment. Do you get the same error?
The code should use Is rather than =, like this
' GOOD CODE '
If ctrl.Container Is fraMovies Then
Explanation. You want to check whether two variables "point" to the same control. Controls are objects: you must use Is not = to check whether two object variables "point" to the same object. This is a classic pitfall in VB6.
One last word. Next time, could you try to post 10 lines or less of actual code, reproducing the error, and give the exact error number and message and the exact line on which it occurs? It really does make it much easier for us to solve your problem - I know it's work for you to shorten the code, but you'll get better answers that way.
EDIT Welcome back! :) You said some controls don't have a Container property. You could try wrapping the test in On Error Resume Next, something like this.
' GOOD CODE '
Dim bMatch As Boolean
Dim ctrl As Control
For Each ctrl In Me.Controls
bMatch = False
On Error Resume Next
bMatch = (ctrl.Container Is fraMovies)
On Error Goto 0
If bMatch Then
ctrl.Enabled = True
End If
Next
To avoid such problems follow the given rules while naming contols
When you name an element in your Visual Basic application, the first character of that name must be an alphabetic character or an underscore.
**Begin each separate word in a name with a capital letter, as in FindLastRecord and RedrawMyForm.
Begin function and method names with a verb, as in InitNameArray or CloseDialog.
Begin class, structure, module, and property names with a noun, as in EmployeeName or CarAccessory.
Begin interface names with the prefix "I", followed by a noun or a noun phrase, like IComponent, or with an adjective describing the interface's behavior, like IPersistable. Do not use the underscore, and use abbreviations sparingly, because abbreviations can cause confusion.
Begin event handler names with a noun describing the type of event followed by the "EventHandler" suffix, as in "MouseEventHandler".
In names of event argument classes, include the "EventArgs" suffix.
If an event has a concept of "before" or "after," use a suffix in present or past tense, as in "ControlAdd" or "ControlAdded".
For long or frequently used terms, use abbreviations to keep name lengths reasonable, for example, "HTML", instead of "Hypertext Markup Language". In general, variable names greater than 32 characters are difficult to read on a monitor set to a low resolution. Also, make sure your abbreviations are consistent throughout the entire application. Randomly switching in a project between "HTML" and "Hypertext Markup Language" can lead to confusion.
Avoid using names in an inner scope that are the same as names in an outer scope. Errors can result if the wrong variable is accessed. If a conflict occurs between a variable and the keyword of the same name, you must identify the keyword by preceding it with the appropriate type library. For example, if you have a variable called Date, you can use the intrinsic Date function only by calling DateTime.Date.

Resources