NeuroAgent

Offsetting Selected Rows in 1C Table Forms: Complete Guide

Learn how to programmatically set offset for selected rows in 1C table forms. Complete guide to highlighting entire rows, manual movement, and Excel equivalents.

How to programmatically set the offset of a selected row in a 1C table form? Is it possible to select an entire row in user mode and move it manually? How to select an entire row at once, rather than individual elements? How to click on a column header in Excel to select an entire row?

NeuroAgent

Programming Row Selection and Shifting in 1C Table Forms

In 1C programming for table forms, there are several methods for managing row selection and shifting. You can programmatically set the offset of selected rows, select entire rows in user mode and manually shift them, as well as use various methods for selecting entire rows instead of individual elements, similar to Excel’s functionality with column headers.

Contents

Programmatic Control of Row Selection

In 1C, programmatic control of row selection in a table form is done through the form object and its elements. The main methods and properties for working with selection include:

  • Elements.TableForm.CurrentRow - getting and setting the current row
  • Elements.TableForm.SelectedRows - collection of selected rows
  • Elements.TableForm.SelectRow() - method for selecting a row

To programmatically set the offset of the selected row, you can use the following approach:

1c
// Get the currently selected row
CurrentRow = Elements.TableForm.CurrentRow;

// If a row is selected
If CurrentRow <> Undefined Then
    // Get the index of the current row
    RowIndex = CurrentRow.Index;
    
    // Set the offset (for example, 2 positions down)
    Offset = 2;
    NewIndex = RowIndex + Offset;
    
    // Check that the new index is within the table bounds
    If NewIndex >= 0 And NewIndex < Elements.TableForm.Rows.Count() Then
        // Set the new current row
        Elements.TableForm.CurrentRow = Elements.TableForm.Rows[NewIndex];
    EndIf;
EndIf;

Selecting multiple rows and mass shifting is also possible through the SelectedRows collection:

1c
// Get the collection of selected rows
SelectedRows = Elements.TableForm.SelectedRows;

// If there are selected rows
If SelectedRows.Count() > 0 Then
    // Set the offset
    Offset = 1;
    
    // Iterate through selected rows in reverse order
    // to avoid problems with index changes
    For i = SelectedRows.Count() - 1 To 0 Step -1 Loop
        CurrentRow = SelectedRows[i];
        NewIndex = CurrentRow.Index + Offset;
        
        // Check boundaries
        If NewIndex >= 0 And NewIndex < Elements.TableForm.Rows.Count() Then
            // Move the row
            Elements.TableForm.Rows.Move(NewIndex, CurrentRow);
        EndIf;
    EndLoop;
EndIf;

Selecting Entire Rows in User Mode

Yes, it’s possible to select an entire row in user mode and manually shift it. For this, the table form must have appropriate settings:

  1. Table form settings:

    • The “Selection mode” property should be set to “Row”
    • Edit mode must be allowed
  2. Manual row shifting:

    • Select a row by clicking on the row header (usually on the left)
    • Drag the selected row to a new position
    • Or use the move buttons in the toolbar

To programmatically support manual row moving, you need:

1c
// In the drag start event handler
&AtClient
Procedure TableFormDragStart(Element, DragData, Source)
    // Check if a table row is being dragged
    If TypeOf(Source) = Type("TableRow") Then
        // Allow the operation
        DragData.Allowed = True;
    EndIf;
EndProcedure

// In the drag end event handler
&AtClient
Procedure TableFormDragEnd(Element, DragData, Target)
    // Process drag completion
    If TypeOf(Target) = Type("TableRow") Then
        // You can add additional logic
        Message("Row successfully moved");
    EndIf;
EndProcedure

Methods for Selecting Entire Rows

In 1C, there are several ways to select an entire row at once, rather than individual elements:

1. Through row headers

If the table form displays row headers, clicking on a row header selects the entire row:

1c
// Setting row header display
Elements.TableForm.ShowRowHeaders = True;

2. Selection by first column

You can configure selection of the entire row when clicking on the first column:

1c
// In the selection start event handler
&AtClient
Procedure TableFormSelectionStart(Element, StandardProcessing, SelectedValue, Source)
    // If clicked on the first column
    If Element.Name = "FirstColumn" Then
        // Select the entire row
        StandardProcessing = False;
        Elements.TableForm.CurrentRow = Elements.TableForm.CurrentRow;
    EndIf;
EndProcedure

3. Mass row selection

To select multiple rows at once, use keyboard shortcuts:

  • Ctrl + click - selection of multiple non-adjacent rows
  • Shift + click - selection of a range of rows
1c
// Programmatic selection of a range of rows
&AtClient
Procedure SelectRowRange(StartIndex, EndIndex)
    // Clear current selection
    Elements.TableForm.SelectedRows.Clear();
    
    // Select rows in the range
    For i = StartIndex To EndIndex Loop
        If i < Elements.TableForm.Rows.Count() Then
            Elements.TableForm.SelectRow(Elements.TableForm.Rows[i], True);
        EndIf;
    EndLoop;
EndProcedure

Analogy with Excel and Implementation in 1C

In Excel, clicking on a column header selects the entire column, and clicking on a row header selects the entire row. In 1C, you can implement similar functionality:

Column selection by header

1c
// In the header formatting event handler
&AtClient
Procedure TableFormHeaderFormatting(Element, Formatting, RowData)
    // If this is a column header
    If Formatting.ElementForm.Header Then
        // Add click handler
        Formatting.ElementForm.SetAction("Click", "SelectEntireColumn");
    EndIf;
EndProcedure

&AtClient
Procedure SelectEntireColumn(Element)
    // Get the column index
    ColumnIndex = Element.Index;
    
    // Select all rows in this column
    Elements.TableForm.SelectedRows.Clear();
    
    For Each Row In Elements.TableForm.Rows Loop
        Elements.TableForm.SelectRow(Row, True);
    EndLoop;
    
    // Set focus on the column
    Elements.TableForm.CurrentColumn = ColumnIndex;
EndProcedure

Row selection by header

1c
// In the header formatting event handler
&AtClient
Procedure TableFormHeaderFormatting(Element, Formatting, RowData)
    // If this is a row header
    If Formatting.ElementForm.HeaderType = RowHeaderType.Row Then
        // Add click handler
        Formatting.ElementForm.SetAction("Click", "SelectEntireRow");
    EndIf;
EndProcedure

&AtClient
Procedure SelectEntireRow(Element)
    // Get the row by header
    Row = Elements.TableForm.Rows[Element.Index];
    
    // Select only this row
    Elements.TableForm.SelectedRows.Clear();
    Elements.TableForm.SelectRow(Row, True);
    
    // Set focus on the row
    Elements.TableForm.CurrentRow = Row;
EndProcedure

Practical Code Examples

Example 1: Moving selected rows up

1c
&AtClient
Procedure MoveSelectedRowsUp(Command)
    SelectedRows = Elements.TableForm.SelectedRows;
    
    If SelectedRows.Count() = 0 Then
        Return;
    EndIf;
    
    // Sort selected rows by index
    SelectedRows.Sort("Index");
    
    // Move each row up
    For Each Row In SelectedRows Loop
        Index = Row.Index;
        If Index > 0 Then
            Elements.TableForm.Rows.Move(Index - 1, Row);
        EndIf;
    EndLoop;
EndProcedure

Example 2: Extended selection with keyboard shortcuts

1c
&AtClient
Procedure TableFormKeyPress(Element, Key, KeyProcessing)
    // Ctrl+A - select all rows
    If Key = Keys.Ctrl + "A" Then
        Elements.TableForm.SelectedRows.Clear();
        
        For Each Row In Elements.TableForm.Rows Loop
            Elements.TableForm.SelectRow(Row, True);
        EndLoop;
        
        KeyProcessing = True;
        Return;
    EndIf;
    
    // Ctrl+Up - select row above
    If Key = Keys.Ctrl + Keys.Up Then
        CurrentRow = Elements.TableForm.CurrentRow;
        If CurrentRow <> Undefined And CurrentRow.Index > 0 Then
            NewRow = Elements.TableForm.Rows[CurrentRow.Index - 1];
            Elements.TableForm.CurrentRow = NewRow;
            Elements.TableForm.SelectRow(NewRow, True);
        EndIf;
        
        KeyProcessing = True;
        Return;
    EndIf;
    
    // Ctrl+Down - select row below
    If Key = Keys.Ctrl + Keys.Down Then
        CurrentRow = Elements.TableForm.CurrentRow;
        If CurrentRow <> Undefined And CurrentRow.Index < Elements.TableForm.Rows.Count() - 1 Then
            NewRow = Elements.TableForm.Rows[CurrentRow.Index + 1];
            Elements.TableForm.CurrentRow = NewRow;
            Elements.TableForm.SelectRow(NewRow, True);
        EndIf;
        
        KeyProcessing = True;
        Return;
    EndIf;
EndProcedure

Example 3: Context menu for row management

1c
// In the form module
&AtClient
Function GetContextMenuForRow(Element, RowData) Export
    Commands = New ValueList;
    
    // Add row management commands
    Commands.Add("Move up", "Move row up", "ExecuteMoveUp");
    Commands.Add("Move down", "Move row down", "ExecuteMoveDown");
    Commands.Add("Duplicate", "Copy row", "ExecuteDuplicateRow");
    Commands.Add("Delete", "Delete row", "ExecuteDeleteRow");
    
    Return Commands;
EndFunction

&AtClient
Procedure ExecuteMoveUp(Command)
    CurrentRow = Elements.TableForm.CurrentRow;
    If CurrentRow <> Undefined And CurrentRow.Index > 0 Then
        Elements.TableForm.Rows.Move(CurrentRow.Index - 1, CurrentRow);
    EndIf;
EndProcedure

&AtClient
Procedure ExecuteMoveDown(Command)
    CurrentRow = Elements.TableForm.CurrentRow;
    If CurrentRow <> Undefined And CurrentRow.Index < Elements.TableForm.Rows.Count() - 1 Then
        Elements.TableForm.Rows.Move(CurrentRow.Index + 1, CurrentRow);
    EndIf;
EndProcedure

&AtClient
Procedure ExecuteDuplicateRow(Command)
    CurrentRow = Elements.TableForm.CurrentRow;
    If CurrentRow <> Undefined Then
        Copy = CurrentRow.Copy();
        Elements.TableForm.Rows.Add(Copy);
        Elements.TableForm.CurrentRow = Copy;
    EndIf;
EndProcedure

&AtClient
Procedure ExecuteDeleteRow(Command)
    CurrentRow = Elements.TableForm.CurrentRow;
    If CurrentRow <> Undefined Then
        Elements.TableForm.Rows.Delete(CurrentRow);
    EndIf;
EndProcedure

Conclusion

Programming table forms in 1C provides extensive capabilities for managing row selection and movement. The main takeaways are:

  1. Programmatic control of selection is done through the CurrentRow and SelectedRows properties, as well as row selection methods.

  2. Manual selection and movement of rows is possible in user mode with proper table form configuration and allowing drag operations.

  3. Complete row selection is achieved through row and column headers, or programmatically through selected element collections.

  4. Excel analogy is implemented through header event handlers and additional functions for selecting entire columns or rows.

  5. Practical recommendations:

    • Use keyboard shortcuts for quick range selection
    • Implement context menus for convenient row management
    • Handle drag start and end events for smooth user interface interaction
    • Check boundaries when programmatically moving rows

For effective work with table forms, it’s recommended to combine programmatic methods with user interactions, creating an intuitive and functional interface.

Sources

  1. Official 1C:Enterprise Documentation - Working with Table Parts
  2. 1C Programming Guide - Table Documents and Forms
  3. 1C Developer Library - Form Element Management
  4. Tips for Optimizing Work with Table Forms in 1C
  5. Examples of Programmatic Control of Table Forms