Matt Hall
Matt Hall

Reputation: 2412

Create an immediate window style log on a form

Is it possible to create something like the immediate window on a form?

I've tried sending various updates to a text box, but the update rate on text box seems to be much slower than what you get with Debug.Print to the immediate window.

Would be good to tell the user what operations are currently being carried out whilst they wait for something to be processed (and without skipping some operations because they are processed quicker than the update rate would seemingly allow).

Upvotes: 1

Views: 662

Answers (3)

Kevin Lyon
Kevin Lyon

Reputation: 1

Just in case anyone ever looks for this again, there IS a way to do what the OP asked, without multiple textboxes.

Screenshot of solution

On your form, add a textbox. A regular textbox will do. Give it a name, like txtLog. Size it to be big enough to display a bunch of text.

Here's a sub to handle the updating:

Private Sub WriteToLogText(strText As String, Optional blnClear As Boolean = False)
     txtLog.SetFocus
     If blnClear = True Then
         txtLog = strText
     Else
         txtLog = txtLog.Text & Chr(13) & Chr(10) & strText
     End If
End Sub

Then call the sub to write your text:

strMsg = "Warning: Commodity '" & Trim(drs("RawCommodity")) & "' is not mapped."
WriteToLogText strMsg

Upvotes: 0

Gord Thompson
Gord Thompson

Reputation: 123559

In the past I had tried using a single multi-line Text Box as a scrolling status window but it seemed to be inordinately fussy when it came to the text selection status (.SelText, .SelLength, .SelLength). In the end I just went with five (5) single-line Text Box controls and "scrolled" them myself.

In the following screenshot the Text Box controls are named txtStatus4, txtStatus3, ... txtStatus0 (from top to bottom)

myForm.png

and the code to update that status "window" (actually a Frame control) is

Private Sub UpdateStatus(StatusText As String)
    Dim i As Long
    For i = 4 To 1 Step -1
        Me.Controls("txtStatus" & i).Value = Me.Controls("txtStatus" & i - 1).Value
    Next
    Me.txtStatus0.Value = StatusText
    Me.Repaint
End Sub

Upvotes: 1

mnieto
mnieto

Reputation: 3874

You can set the textbox (or label) text and then call the DoEvents method. This last call is important because is supossed you are executing a long process and screen will redraw only on idle time.

Alternatively, you can use the status bar to notify your progress:

SysCmd acSysCmdSetStatus, "Doing some long task, please wait..."
'Do your work
SysCmd acSysCmdSetStatus, ""

If you can measure your progress, it's possible to include a progress bar. I.e. processing a recordset:

   bk = rs.Bookmark
   rs.MoveLast
   r = SysCmd(acSysCmdInitMeter, caption, rs.RecordCount)
   rs.Bookmark = bk

   Do Until rs.EOF
    'Do something
    i = i + 1
    If i Mod 10 = 0 Then     'Do not update the meter for every processed record
        SysCmd acSysCmdUpdateMeter, i
    End If
    rs.MoveNext
   Next
   SysCmd acSysCmdRemoveMeter

Upvotes: 2

Related Questions