CHR(9) Inserting atab into a string

ECEK

Registered User.
Local time
Today, 12:30
Joined
Dec 19, 2012
Messages
717
I was trying to concatenate two fields in my query with a tab.
I assumed:
Code:
[Field1]&Chr(9)&[Field2]
But to no avail.

Am I missing something ?
 
Where are you doing this?
Please show all the relevant code.
 
Where are you doing this?
Please show all the relevant code.
 
Put space between &.
 
Please post the SQL view of your query.

eg

Code:
Select [Field1] & Chr(9) & [Field2] as MyTest, Field3
From Table1
 
Last edited:
Code:
SELECT [Field1] & Chr(9) & [Field2] AS Expr1
FROM Table1;
 
What is the result when you run the query? Error? Msg?
 
The data in Field1 is "Before Tab"
The data in Field2 is "After Tab"
Result is "Before TabAfter Tab"

I'm expecting to see "Before Tab After Tab"

(I couldn't use the tab button in this text box to illustrate which leads me to the conclusion that tab does not have a universal length and that that parameter would need to be set)
 
As one would with Word: I am trying to insert a tab into my string of text
 
You format the calc field of query as Rich text. But again it will not add the tab but only a space (representing the tab). If you cant see the Format in property sheet close the query and right click it on the nav pane and choose edit.
 
I created a small vba script
Code:
Sub getit()
    Dim x As String: x = ">|" & Chr(9) & "|<"
    Dim i As Integer
    Debug.Print " i    " & "x       Chr "
    Debug.Print
    For i = 1 To Len(x)
        Debug.Print i & Space(2) & x & "   " & Asc(Mid(x, i, 1))
    Next i
End Sub



Code:
 i    x       Chr 

1  >|   |<   62
2  >|   |<   124
3  >|   |<   9
4  >|   |<   124
5  >|   |<   60

I'm pretty sure the tab chr(9) is converted to spaces when it gets printed/displayed.
 
You can use the String function to insert a specified number of repeating characters of your choice.

For example if you want to add 4 spaces to represent a tab between Field1 and Field2 then use
Code:
[Field1] & String(4," ") & [Field2)

Similarly String(5,"*") gives *****
 
The tab character requires the app to have knowledge of 'columns' in the text which in turn means things like knowing the width of a control and the characters. So cannot work within the context of a string.

building on Colin's suggestion you could use something like

[Field1] & String(10-len([field1])," ") & [Field2)

which will allow for varying lengths of field1 - but still will not allow for the fact that a 'W' character takes up more width than 'I' character
 
The tab character requires the app to have knowledge of 'columns' in the text which in turn means things like knowing the width of a control and the characters. So cannot work within the context of a string.

building on Colin's suggestion you could use something like

[Field1] & String(10-len([field1])," ") & [Field2)

which will allow for varying lengths of field1 - but still will not allow for the fact that a 'W' character takes up more width than 'I' character

...unless you use a monospaced (AKA fixed width ) font such as Courier New or Lucida Console where all characters are the same width
This is how I've lined up the times on the screenshot below

attachment.php


Unfortunately this gives a rather old fashioned appearance

And for anyone who cares this is part of the code where the number of ... depends on the length of the text strings before & after

Code:
L = Len(strEntry)
S = Len(strSuccess)
T = Len(Format((ShowTickCount / 1000), "0.00") & "s")

strEntry = strEntry & String(80 - L, ".") & strSuccess & String(15 - S - T, ".") & Format((ShowTickCount / 1000), "0.00") & "s"
 

Attachments

  • Capture.PNG
    Capture.PNG
    4.5 KB · Views: 1,570
Ridders, I discovered an easier way to do that, and your String function is part of it.

1. Build a constant length string of dots

Dots = STRING(desired-length, ".")

2. Insert first part

Mid(dots, 1, Len(PFX) ) = Pfx

3. Insert second part.

Mid(dots, Len(Dots) - Len(Sfx), Len(Sfx) ) = Sfx

I've used this approach many times. For those not familiar with the STRING function, here is a reference.

https://support.office.com/en-us/article/string-function-4808c43b-7640-4334-87fc-457499c185b1

A further comment is in order: You must be careful when using the tab character. You see, it is a holdover from the days of ASCII Teletypes. (Trust me, as a Navy contractor and as a 50-year programmer, I've seen Teletypes.) The TAB, being a carriage control character, relies on TAB STOPS, which originally were mechanical things that were, by tradition set every 8 columns. But if you had special forms loaded to your printing device, the tab stops would be set to the starting edge of each field on your special forms. Ah, for the days of fan-folded special card-stock printers... but I'm getting a bit nostalgic here.

Anyway, for a display device, a TAB means exactly what the designer of the FONT wanted it to mean, and sometimes that is NOTHING. So when you put a TAB character in a string and display it, you are at the mercy of the font, and as is well known, computers have no mercy.

That might not be the case when you actually PRINT something that contains a TAB because the printing device's driver might implement that TAB in software. Therefore, when using a TAB for something, consider WHERE you will use it. It won't always work because on a display device are there no tabs that you didn't set yourself.

In fact, consider MS WORD. You can set TAB stops there because WORD is SIMULATING a physical printer to give you WYSIWYG displays. There, TAB means something but only because it is TRYING to look like a printer's output.

If you create a text file using OPEN file FOR OUTPUT as #1 (or something similar) and use a PRINT #1 to write text to the file, then the TAB character acts as though you have software tab stops. But again, it is EMULATING printer behavior.

Moral of the story? If you aren't going to output to a real printer with real carriage control, use some other method to align your text output.
 
Last edited:
Hi Doc

Thanks for this
Actually I only showed you part of the code which logs the progress of overnight updates which run automatically at a specified quiet time
As the code runs, each of the 50 or so procedures adds an entry with either Success or Fail after the time
To make life more complex, this is used with many different clients (schools), so the code allows for different width screens to ensure all the text is visible without scrolling across
Here's a bit more of the code.

Code:
Sub WriteTextEntry(strEntry As String)
On Error GoTo err_writetextentry
Dim L, S, T, icount As Integer

L = Len(strEntry)
S = Len(strSuccess)
T = Len(Format((ShowTickCount / 1000), "0.00") & "s")

If Left(strEntry, 1) = "=" Then 'for header / footer . . .omit timing
    strEntry = strEntry
Else 'show OK/Fail & timing
    If Len(strEntry) < 105 Then  ' - value changed from 60 to 105 to increase width
    'strEntry = strEntry & String(80 - L, ".") & strSuccess & String(15 - S - T, ".") & Format((ShowTickCount / 1000), "0.00") & "s" & "   "
        If 98 - L > 0 Then
       '     strEntry = strEntry & String(83 - L, ".") & strSuccess & String(15 - S - T, ".") & Format((ShowTickCount / 1000), "0.00") & "s" & "   "
            strEntry = strEntry & String(83 - L, ".") & String(15 - T, ".") & Format((ShowTickCount / 1000), "0.00") & "s" & "    " & strSuccess
        Else
       '     strEntry = strEntry & strSuccess & String(15 - S - T, ".") & Format((ShowTickCount / 1000), "0.00") & "s" & "   "
            strEntry = strEntry & String(15 - T, ".") & Format((ShowTickCount / 1000), "0.00") & "s" & "    " & strSuccess
        End If
    Else ' - value changed from 58 to 100 to increase width
      '  strEntry = Left(strEntry, 100) & String(2, ".") & strSuccess & String(15 - S - T, ".") & Format((ShowTickCount / 1000), "0.00") & "s" & "   "
        strEntry = Left(strEntry, 100) & String(2, ".") & String(15 - T, ".") & Format((ShowTickCount / 1000), "0.00") & "s" & "    " & strSuccess
    End If
End If

....

End Sub

PHEW!
It also creates a log file of this info and emails it to the program admin each night to alert him/her if anything went wrong

As is often the case, the code was simple at first with just one clause using TickCount & got built on multiple times with the use of the String function.

Looking at your code, I'm wondering whether to scrap use of TickCount & start again as it does look simpler. Whether it will still be simpler when I add the Success/Fail & allow for different monitors is, of course, another matter

Thanks again
 

Users who are viewing this thread

Back
Top Bottom