CHR(9) Inserting atab into a string (1 Viewer)

ECEK

Registered User.
Local time
Today, 22:44
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 ?
 

jdraw

Super Moderator
Staff member
Local time
Today, 17:44
Joined
Jan 23, 2006
Messages
15,379
Where are you doing this?
Please show all the relevant code.
 

jdraw

Super Moderator
Staff member
Local time
Today, 17:44
Joined
Jan 23, 2006
Messages
15,379
Where are you doing this?
Please show all the relevant code.
 

arnelgp

..forever waiting... waiting for jellybean!
Local time
Tomorrow, 05:44
Joined
May 7, 2009
Messages
19,229
Put space between &.
 

jdraw

Super Moderator
Staff member
Local time
Today, 17:44
Joined
Jan 23, 2006
Messages
15,379
Please post the SQL view of your query.

eg

Code:
Select [Field1] & Chr(9) & [Field2] as MyTest, Field3
From Table1
 
Last edited:

ECEK

Registered User.
Local time
Today, 22:44
Joined
Dec 19, 2012
Messages
717
Code:
SELECT [Field1] & Chr(9) & [Field2] AS Expr1
FROM Table1;
 

jdraw

Super Moderator
Staff member
Local time
Today, 17:44
Joined
Jan 23, 2006
Messages
15,379
What is the result when you run the query? Error? Msg?
 

ECEK

Registered User.
Local time
Today, 22:44
Joined
Dec 19, 2012
Messages
717
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)
 

ECEK

Registered User.
Local time
Today, 22:44
Joined
Dec 19, 2012
Messages
717
As one would with Word: I am trying to insert a tab into my string of text
 

arnelgp

..forever waiting... waiting for jellybean!
Local time
Tomorrow, 05:44
Joined
May 7, 2009
Messages
19,229
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.
 

jdraw

Super Moderator
Staff member
Local time
Today, 17:44
Joined
Jan 23, 2006
Messages
15,379
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.
 

isladogs

MVP / VIP
Local time
Today, 22:44
Joined
Jan 14, 2017
Messages
18,209
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 *****
 

CJ_London

Super Moderator
Staff member
Local time
Today, 22:44
Joined
Feb 19, 2013
Messages
16,610
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
 

isladogs

MVP / VIP
Local time
Today, 22:44
Joined
Jan 14, 2017
Messages
18,209
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



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,291

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 16:44
Joined
Feb 28, 2001
Messages
27,146
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:

isladogs

MVP / VIP
Local time
Today, 22:44
Joined
Jan 14, 2017
Messages
18,209
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

Top Bottom