How do I stack fields vertically in Crystal Reports 2008

10,216

Solution 1

I already described how to manually align the fields using the Object Size and Position dialog. I have now written a Sikuli script to automate that use of the dialog. I successfully used the script to stack about 70 new fields underneath existing stacked ones.

To use this script, copy and paste its contents into Sikuli IDE. Open Crystal Reports and find the field at the bottom of the existing stack. Make sure the new field you want to add to the bottom of the stack exists and is visible on-screen. Select the field at the bottom of the stack. Then switch to Sikuli and hit CtrlR to start the script. It will switch to Crystal Reports and open the Size and Position dialog, read the existing values for the field at the bottom of the stack, and close the dialog. You now have 1.5 seconds (configurable) to select the new field by clicking on it. Now the script will open the Size and Position dialog again and set the X, Y, Width, and Height so that the selected field is placed underneath the previous one. Specifically, the X, Width, and Height are set to the same as the above field, and the Y is set as I described in my other answer. You can change the configuration variable VERTICAL_SPACE_BETWEEN_FIELDS to add space between each field or cause them to overlap, if you want.

The script takes about 5 seconds to align one field. If that's too slow, you can try decreasing the time in or removing some of the wait() calls. I added the wait() calls because the script sometimes copied or pasted the wrong value if it went too fast.

One nice thing about this script is that it is chainable. Right after it finishes, the newly-aligned field will still be selected. So if you have another field you want to add under that field, you can just run the script again with CtrlR, and get ready to click on the next field in the middle. If you plan to chain many times, you can increase the 1 in range(1) and add wait(<num_of_seconds>) below mainAction() so that the script repeats itself automatically. Just keep in mind that chaining requires that the next field to add be visible on screen, so you can select it with the mouse.

I saved the script file as "Align Fields in Crystal Reports.sikuli".

# Crystal Reports: stack prompt-selected field under start-selected field

VERTICAL_SPACE_BETWEEN_FIELDS = 0.000
WAIT_TIME_FOR_USER_SELECT_NEW_FIELD = 1.5

def mainAction():
    # read size and position of bottom of stack
    above = dict()
    openSizeAndPositionDialog()
    above['x'] = copySelectedText()
    moveToNextField(2)
    above['y'] = copySelectedText()
    moveToNextField()
    above['width'] = copySelectedText()
    moveToNextField(2)
    above['height'] = copySelectedText()
    print("above", above)
    wait(0.05)
    type(Key.ESC)

    # calculate size and position of next field in stack
    new_field = dict()
    new_field['x'] = above['x']
    new_field['y'] = str(float(above['y']) + float(above['height']) + VERTICAL_SPACE_BETWEEN_FIELDS)
    new_field['width'] = above['width']
    new_field['height'] = above['height']
    print("new field", new_field)

    waitForUserToSelectNewField()

    # set size and position of next field
    openSizeAndPositionDialog()
    paste(new_field['x'])
    moveToNextField(2)
    paste(new_field['y'])
    moveToNextField()
    paste(new_field['width'])
    moveToNextField(2)
    paste(new_field['height'])
    wait(0.1)
    type(Key.ENTER)

def openSizeAndPositionDialog():
    type(Key.ALT + "a" + "z")
    wait(0.05)

def copySelectedText():
    type("c", KeyModifier.CTRL)
    wait(0.05)
    return Env.getClipboard()

def moveToNextField(numTimes=1):
    for i in range(numTimes):
        type(Key.TAB)
        wait(0.05)

def waitForUserToSelectNewField():
    # I'll do it without the popup, because switching to the popup and then closing it is a pain
    wait(WAIT_TIME_FOR_USER_SELECT_NEW_FIELD)

    #popup("select the new field to align under the old one, then press OK")
    #wait(0.2)

App.focus("Crystal Reports")
wait(0.2) # give you time to release CTRL, which would interfere with the script
for i in range(1):
    mainAction()

Solution 2

The manual approach will work best. In addition to Snap to Grid and vertical guidelines, as Mark suggests, you should also use multiple Details and Group Header sections. Multiple sections keep things better organized.

I avoid Crystal Reports 'wizards' whenever I can--this is after 15 years of working with the product (since v4).

Solution 3

As an alternative method to manually align fields so their borders are touching, you could use the Object Size and Position dialog. You can access it by opening the "Format" menu or a field's context menu, then choosing the menu item "Size and Position...".

Object Size and Position dialog in Crystal Reports

Follow this procedure to add a new field to the bottom of a column of vertically stacked fields:

  1. Select the current bottom field in the column.
  2. Open the Size and Position dialog.
  3. Copy its X value down.
  4. Add the Y value to the Height, and copy that down.
  5. Close the dialog.
  6. Select the new field that you want to move to the bottom of the column.
  7. Open the Size and Position dialog.
  8. Enter the copied X value as the X value, and the copied sum as the Y value.
  9. Close the dialog.

If it's easier, you could replace the steps about the X value with the command "Format" > "Align" > "Lefts" (or "Centers", or "Rights").

This method is easier to automate than dragging fields with the mouse. If you have to align many fields, you can automate much of this procedure using AutoHotkey or Sikuli. I actually did end up automating this – I wrote this Sikuli script.

Solution 4

Quick and dirty method. If you want the fields to be evenly distributed and you don't have many fields to stack vertically then create a text box with the height of two fields (assumes they are the same height) plus the desired space. So assuming you wanted a vertical spacing of .08 Height and field height was 0.167 create a text box then using Object size and position dialog set the Height .414 (0.167 + 0.08 + 0.167). Now place the fields in desired order vertically. Don't worry about spacing at the moment.

  1. Place the text box beside the first field
  2. Select the text box first.
  3. While holding the shift key select the first field so that both the field and the text box are both selected, but the field is the primary object.
  4. Right Click for the context menu.
  5. Select Align, Tops. The TextBox will now be aligned with the top of the first field.
  6. Select the next field below.
  7. Holding the shift key select the TextBox so that both the next field and the text box are both selected, but the textbox is now the primary object.
  8. Select Align, Bottoms. This will move the field to the bottom border of the textbox which will move the field to the correct vertical Y position and give you the desired margin.
  9. Repeat steps 2 - 8 for each subsequent field (so select text box and 2nd field as primary object align tops, then 3rd field and textbox as primary object align bottoms, etc).
Share:
10,216
ShoeLace
Author by

ShoeLace

i have no defining features

Updated on June 08, 2022

Comments

  • ShoeLace
    ShoeLace almost 2 years

    I am using Crystal Reports 2008 to develop some reports (on an oracle database ).

    I have a number of text fields in my design/layout that I want to be positioned in a vertical stack with no space between.

    Using Oracle reports I can select the fields and do an align->stackvertical, but there does not seem to be a similar option in CR2008

    The "Align" option has tops,middles,bottoms,baseline,lefts,centres,rights,to grid. none of which do what i want.

    Is there an easy way to do this? or do I just have to position them manually? (maybe using snap-to-grid)

  • ShoeLace
    ShoeLace about 11 years
    no.. i dont want the text to be vertical.. i want the fields to be touching each other with no space between them
  • safetyOtter
    safetyOtter over 9 years
    This is perfect for my needs, thanks for posting. Would suggest that you tell people to disable snap to grid, it was making this behave weirdly when i first tried it.