Home / windows overview / 1c managed form value table add column. It is important to never confuse an object property with an object method.

1c managed form value table add column. It is important to never confuse an object property with an object method.

Here is a little fact to start - simple examples work with a table of values:

1. Create a table of values

ValueTable = New ValueTable;


2. Create columns of the table of values:

ValueTable.Columns.Add("Name");
ValueTable.Columns.Add("Last Name");


3. Add new rows using column names:


NewString.Name = "Vasily";
NewRow.LastName = "Pupkin";


4. How to search for a value in the value table:
It is necessary to find a table row containing the desired value.

FoundString = ValueTable.Find(LookupValue);


5. Find the first occurrence in certain columns of a table of values

FoundString = ValueTable.Find(LookupValue, "Supplier, Buyer");


6. If you need to find all occurrences in the table of values:
We use the search structure.

SearchStructure = Structure("Employee", LookupValue);
ArrayFoundStrings = ValueTable.FindStrings(SearchStructure);


Let's create a search structure, each element of which will contain the name of the column as a key and the searched value in this column as a value. We pass the Search Structure as a parameter to the FindStrings() method. As a result, we get the rows of the table.
If we add the search for the desired value to the search structure, for example, also in the column Responsible, then as a result of applying the FindRows() method, we will get all rows where both Employee and Responsible are equal to the desired value.

7. How to loop through a table of values ​​in random order

For Each CurrentRow From ValueTable Loop
Report(CurrentLine.Name);
EndCycle;

Do the same using indexes:

SeniorIndex = ValueTable.Count() - 1;
For MF = 0 by SeniorIndex Cycle
Report(ValueTable[Count].Name);
EndCycle;


8. Deleting an Existing Value Table Row

ValueTable.Delete(RemoveRow);

by index

ValueTable.Delete(0);


9. Deleting an existing column of the table of values

ValueTable.Columns.Delete(RemoveColumn);


by index

ValueTable.Columns.Delete(0);

It must be taken into account that deleting a row (or column) “from the middle” of the table of values ​​will lead to a decrease by one of the indexes of the rows that were “after” the deleted

10. How to fill in the value table if the column names are contained in variables?

NewRow = ValueTable.Add();
NewRow[ColumnName] = Value;


11. How to fill the entire column of the table of values ​​with the desired value?
The FiscalAccounting Flag column in the value table of the Value Table must be filled with the value False

ValueTable.FillValue(False, "Fiscal Accounting Flag");


We use the FillValues() method for the table of values. The first parameter is the value to fill. The second parameter is the name of the filled column.

12. How to fill the table of values ​​"TableRecipient" with the data of the table of values ​​"SourceTable"?

If the Receiver Table does not yet exist at the time of the operation, or you do not need to save its previous columns, you can create it as full copy original

TableReceiver = TableOriginal.Copy();


Option two: table TableReceiver exists, and it's a pity to lose its columns and restrictions on column data types. But you need to fill in the data for the columns whose names match the names of the source table.

Partial data transfer for columns with matching names:

For Each Row Of SourceTable From SourceTable Loop
FillPropertyValues(NewString, SourceTableString);
EndCycle


For each row of the source table, a new row is added to the destination table and the values ​​are filled in those columns of the new table whose names match the names of the columns in the source table

If the tables don't have columns with the same name, the destination table will end up with as many rows with null values ​​as there were rows in the source table.
If for some columns of the same name the data value type from the source table does not fall into the array of allowed types of the column of the destination table, we will get empty values ​​in such fields.
Let's consider the third case. In the case of columns with the same name, the column of the destination table must be brought into full compliance with the column of the source table.

Full data copy for columns with matching names

SimilarColumns = New Array();

For Each Column From SourceTable.Columns Loop
MatchingColumn = TableReceiver.Columns.Find(Column.Name);

If MatchedColumn<>Undefined Then

// Get column properties.
Name = Column.Name;
ValueType = Column.ValueType;
Title = Column.Title;
Width = Column.Width;

// Replace columns in the destination table.
Index = TableReceiver.Columns.Index(CoincidentColumn);

TableReceiver.Columns.Delete(Index);
TableReceiver.Columns.Insert(Index, Name, ValueType, Title, Width);

// Add the next name of the matching columns to the array.
Same-nameColumns.Add(Column.Name);

EndIf;

EndCycle;

// Loop through the rows of the source table.
For each Row of SourceTable From SourceTable Loop

// Add a new row to the destination table.
NewString = TableReceiver.Add();

// Fill in values ​​in matching cells.
For each NameColumns Of Same NameColumns Loop
NewString[ColumnName] = SourceTableString[ColumnName];

EndCycle;

EndCycle;


We will have to replace the column in the destination table with a new one, whose properties will fully match the column of the source table.
Therefore, if a column of the same name is found in the recipient table, we collect in variables all the properties for the new column. Next, delete the old one and create a new column. Then we loop through the rows of the source table.
In the loop, we add a new row to the recipient table and open a loop through the names of the columns in the array of matching columns.
Inside this nested loop, we fill the cells of the recipient table with the data of the cell of the source table.

13. How to add columns to the table of values ​​"Table of Values" with type restrictions?

When adding a column, you can simply specify its name, and do not touch the second parameter of the Add() method. In this case, the data type of the column is arbitrary.

Adding a column without specifying a data type

// Add a column with no type restrictions.
ValueTable.Columns.Add("Object");


You can fill in the value of the second parameter. It is necessary to pass a description of the type allowed for the column there. The description itself can be obtained using the constructor, passing the string type name as a parameter to the latter (if there are many types, then separated by commas) or an array of valid types.

Adding a column specifying the data type

// Restrictions on column data types:
// Only elements of the "Contractors" directory.
ValueTable.Columns.Add("Account", New TypeDescription("ReferenceReference.Accounts"));


If there is a string among the types allowed for filling in the column data, you can limit its bit depth (length), specify the use of a variable or fixed length. All this is provided by creating an object using the StringQualifiers constructor. Further, this object will be used as one of the parameters of the TypeDescription constructor.

Using qualifiers to specify the data type of a value table column

// Prepare and set limits for String type data.
String Qualifiers = New String Qualifiers(20, ValidLength.Variable);
AllowedTypes = NewTypeDescription("String",StringQualifiers);
ValueTable.Columns.Add("NoteStringShort", ValidTypes);


You can do the same for number and date qualifiers.
Please note: the type description can be built by the constructor both "from scratch", and you can use an existing type description as a basis

Using Existing Type Declarations to Specify the Data Type of a Value Table Column

// Extension of the previously used description of types.
Number Qualifiers = New Number Qualifiers(10, 2, ValidSign.Non-negative);
DateQualifiers = New DateQualifiers(DateParts.Date);
ExtendedValidTypes = NewTypeDescription(ValidTypes, "Number, Date",NumberQualifiers,DateQualifiers);

ValueTable.Columns.Add("Note", ExtendedAllowedTypes);

In order to take into account money and goods, different tables are widely used in business. Almost every document is a table.

One table lists the goods to be shipped from the warehouse. In another table - the obligation to pay for these goods.

Therefore, in 1C, work with tables occupies a prominent place.

Tables in 1C are also called "table parts". Reference books, documents and others have them.

The query returns a table as a result of its execution, which can be accessed in two different ways.

The first - faster - selection, getting rows from it is possible only in order. The second is unloading the query result into a table of values ​​and then random access to it.

//Option 1 - sequential access to query results

// get table
Selection = Query.Execute().Select();
// bypass all rows of the query result in order
While Selection.Next() Loop
Report(Selection.Name);
EndCycle;

//Option 2 - uploading to the table of values
Query = New Query("SELECT Name FROM Directory.Nomenclature");
// get table
Table = Query.Execute().Upload().
// then we can also bypass all lines
For each Row from Table Loop
Report(String.Name);
EndCycle;
//or arbitrarily access strings
String = Table.Find("Shovel", "Name");

An important feature is that in the table, which is obtained from the result of the query, all columns will be strongly typed. This means that by requesting the Name field from the Nomenclature lookup, you will receive a column of the String type with an allowable length of no more than N characters.

Table on the form (thick client)

The user works with the table when it is placed on the form.

We discussed the basic principles of working with forms in the lesson on and in the lesson on

So, let's place the table on the form. To do this, you can drag the table from the control panel. Similarly, you can select the Form/Insert control from the menu.

Data can be stored in a configuration - then you need to select an existing (previously added) tabular part of the configuration object whose form you are editing.

Click the "..." button in the Data property. In order to see the list of tabular parts, you need to expand the Object branch.

When choosing a tabular part, 1C itself will add columns to the table on the form. The strings entered by the user into such a table will be automatically saved along with the directory/document.

In the same Data property, you can enter an arbitrary name and select the ValueTable type.

This means that an arbitrary table of values ​​has been selected. It will not automatically add columns, it will not be automatically saved, but you can do whatever you want with it.

By right clicking on the table you can add a column. In the properties of the column, you can specify its name (for reference in the 1C code), the column heading on the form, the connection with the attribute of the tabular part (the latter - if not an arbitrary table, but a tabular part is selected).

In the table properties on the form, you can specify whether the user can add/delete rows. A more advanced form is the ViewOnly checkbox. These properties are useful for organizing tables intended for displaying information, but not for editing.

To manage the table, you need to display the command panel on the form. Select the menu item Form/Insert Control/Command Panel.

In the properties of the command bar, select the Autocomplete checkbox so that the buttons on the toolbar appear automatically.

Table on form (thin/managed client)

On a managed form, these actions look a little different. If you need to place a tabular section on the form, expand the Object branch and drag one of the tabular sections to the left. And that's it!

If you need to place a table of values, add a new form attribute and specify the type in its properties - a table of values.

To add columns, use the right mouse button menu on this form attribute, item Add attribute column.

Then also drag the table to the left.

In order for the table to have a command bar, in the table properties, select the values ​​in the Usage - Command bar position section.

Exporting a table to Excel

Any 1C table located on the form can be printed or uploaded to Excel.

To do this, right-click on an empty space in the table and select Show List.

In a managed (thin) client, similar actions can be performed using the menu item All actions/Display list.

The value table in the 1C 8.3 platform (8.2) is a universal collection of values ​​that a developer can use in software development to implement their algorithms. In fact, the 1C value table is a dynamic set of values ​​\u200b\u200bthat have columns and columns.

Articles about other universal collections of values ​​in 1C

Learn programming in 1C in a place from my book "Program in 1C in 11 steps"

  1. The book is written in clear and simple language - for a beginner.
  2. Learn to understand 1C architecture;
  3. You will begin to write code in 1C language;
  4. Master the basic techniques of programming;
  5. Consolidate the acquired knowledge with the help of a task book;

An excellent guide to developing in a managed 1C application, both for novice developers and experienced programmers.

  1. Very accessible and understandable language
  2. The book is sent to email in PDF format. Can be opened on any device!
  3. Understand the ideology of a managed 1C application
  4. Learn how to develop a managed application;
  5. Learn to design managed forms 1C;
  6. You will be able to work with the basic and necessary elements of managed forms
  7. Programming under a managed application will become clear

Promo code for a 15% discount - 48PVXHeYu


If this lesson helped you solve any problem, liked it or was useful, then you can support my project by transferring any amount:

can be paid manually:

Yandex.Money — 410012882996301
Web Money - R955262494655

Join my groups.

Posted on 21 September 2011

Table of values ​​1C - part 3. metadata. Iterating over the columns of the table of values

In this article, I will tell you how to work with a table of values ​​of an "unknown" structure, how to iterate through the columns of a table of values, how to extract data from columns and rows without using column names. (This article refers to a series of articles 1C from scratch; programming 1c from scratch; table of values ​​1c)

To explain the material and in order to be able to run our examples of program code "live", we need some test table of values ​​1C. Part of our examples will extract data from a table of values, so we will make a table with three columns "Last Name", "First Name", "Patronymic" and enter a small amount of data into it - as many as 3 rows :)

So, let's create a test table of 1C values ​​and fill it in:

MyTR = New ValueTable; // create a new table of values ​​stored in the "MyTR" variable MyTR.Columns.Add("Last name"); // create the column "Last name" MyTR.Columns.Add("First name"); // create the "Name" column MyTM.Columns.Add("Patronymic"); // create the "Middle name" column // add the first row to our table of values ​​NewRow = MyТЗ.Add(); NewLine.Surname = "Chapaev"; NewString.Name = "Vasily"; NewString.Patronymic = "Ivanovich"; // add the second line NewLine = MyТЗ.Add(); NewLine.Lastname = "Dzerzhinsky"; NewString.Name = "Felix"; NewLine.Patronymic = "Edmundovich"; // add the third line NewLine = MyTR.Add(); NewRow.LastName = "Kotovsky"; NewString.Name = "Gregory"; NewString.Patronymic = "Ivanovich";

Our test table consists of three columns: First name, Last name, Patronymic; and has three completed lines with the names of the heroes of the Civil War.

The first code sample is iterating through the columns of the 1C value table as a collection.

// display the names of all columns of the TK For Each Column From My TK.Columns Notify loop("Column name: " + Column.Name); EndCycle;

Our loop will display all the column names in the 1C message box:

Column name: Last name Column name: First name Column name: Middle name

We see that a special collection loop is used to iterate through the columns, similar to the row iteration loop (in the last article). MyTM.Columns- this is a collection of columns of the table of values ​​1C "MoyaTZ". The collection contains objects of type "ColumnValueTable" Each object of this type is a column of the value table and contains properties and methods. Referring to these properties and methods, we get the necessary information about one column or perform some other actions with it.

For example, accessing the property "Name" (Column.Name) we get the name of the current column.

I want to draw your attention to the title of the cycle: "For Each Column From MyTR.Columns Loop" Variable named "Column" invented by us. It is not necessary to use the same name. You can name this variable whatever you like, for example "MyCurrentColumn" Then the example above would look like this:

// print the names of all columns of the TK For Each MyCurrentColumn From MyTK.Columns Notify Loop("Column name: " + MyCurrentColumn.Name); EndCycle;

When the 1C execution subsystem encounters a cycle of this kind, at each pass of the cycle, it assigns one element from our collection to the variable with the specified name, in this case - one element of the collection value table columns MyTM.Columns And then we refer to the variable that contains the current column, and use the property "Name".

I suggest displaying the number of each column in the column collection next to the column name:

// display the number and names of all columns of the table of values ​​For Each Column From MyTR.Columns LoopColumnNumber = MyTR.Columns.Index(Column); // get the column number ColumnName = Column.Name; // get the column name Report("Column number:" + Column number + " Column name: " + Column name); EndCycle;

The text will be displayed in the 1C message box:

Column number:0 Column name: Last name Column number:1 Column name: First name Column number:2 Column name: Middle name

Let's pay attention to the fact that the columns in the table of values ​​1C are numbered starting from zero, just like the rows of the table of values.

The number of columns in the table of values ​​1C

To find out the number of columns in the value table, we use the "Number()" method on the column collection.

Number ofColumns = MyTM.Columns.Number(); Report(Number of Columns);

The number "3" will be displayed on the screen. Indeed, in our table there are three columns: "Last name", "First name", "Patronymic"

Obtaining a column object by its number (index) and iterating over columns using the column index

Let's make a loop through all the columns of the table of values ​​using the column indices (numbers). Remember that column numbering starts from zero. Therefore, we must increase the counter of the cycle "Sh" from zero to a number equal to the number of columns minus one.

For SC = 0 By MyTM.Columns.Quantity() - 1 Loop CurrentColumn = MyTM.Columns[SC]; Notify(CurrentColumn.Name); EndCycle;

On the screen we will get the following

Full Name

I think that this example was clear. We turned to the method Quantity() column collections" MyTM.Columns.Quantity()", got the number of columns, and started a loop with a counter from zero before number of columns minus one. Inside the loop, we get each column from the column collection and assign the current column object to a variable CurrentColumn Next, the variable CurrentColumn we access the property Name and display the value of this property on the screen: Notify(CurrentColumn.Name);

It is important to never confuse an object property with an object method.

A property is a kind of static value and access to it is written without brackets, for example CurrentColumn.Name. A method is essentially a procedure or function of an object, and calls to procedures and functions are always written with parentheses (even if there are no input parameters). For example: MyTM.Columns.Quantity()

If we refer to the method, forgetting to write parentheses, the 1C interpreter will give us an error message and will not run the code for execution. Since the interpreter will assume that we are not accessing a method, but a property - because there are no brackets. And it will not be able to find properties with that name (because there is only a method with that name) - which will be said in the error message.

This is what the interpreter will write if I forget to put parentheses in a method call in such a wrong way MyTM.Columns.Quantity(no parentheses after "Quantity()"):

Object field not found (Count)

In this case, "field" and "property" should be understood as synonyms, or an inaccuracy in the terminology of 1C developers. They use both of these words to refer to the same concept. Though in other programming languages ​​these terms can mean different concepts.

Obtaining data from the 1C value table using column numbers

I offer you, for starters, a simple example of getting data from the first row of our table. Please note that we are using the pre-filled table from the beginning of the article. We know for sure that the table has the first row and at least one column. If we apply this example to an empty table, an error will occur. So:

FirstLine = MyTR; // get the first row (numbering from zero) ColumnFirstValue = RowFirst; // get the value of the first column (column numbering is also from zero) Report(FirstColumnValue); // display the value of the first column in the first row of the table

The screen will display:

Chapaev

We first got the value table row object by accessing the value table using the [...] operator. (if you forgot how to do this, you can look at previous articles) Inside the operator, we passed the argument "0". This is the index of the first row of the table of values. FirstLine = MyTR;

Further, we also have the right to refer to the string object using the [...] operator. Inside this statement, we passed the column number of the table of values, in this case also "0". And thus we got the value of the column with the number "0" for current line tables numbered "0". We displayed this value on the screen and it represents the string "Chapaev".

Let's complicate our example a bit:

FirstLine = MyTR; // get the first line (numbered from zero) Report(FirstLine); // display the value of the first column in the first row of the table Report(FirstRow); // display the value of the second column in the first row of the table Report(FirstRow); // display the value of the third column in the first row of the table

Now we have displayed the values ​​from all three columns of the first row of our table of values:

Chapaev Vasily Ivanovich

Now I am modifying this example further so that we can do without a variable "First line"

Notify(MyTM); // display the value of the first column in the first row of the table Report(MyTR); // display the value of the second column in the first row of the table Report(MyTR); // display the value of the third column in the first row of the table

The screen will be the same.

Chapaev Vasily Ivanovich

We saw in the example above that to access a value that is in a specific row and specific column of a table of values, we can use the consecutive call of two operators [...] in this form: ValueTable[IndexRows][IndexColumns]

So, we are ready to create a loop over and get the data of all rows and all columns using row and column indices:

For RowCount = 0 By MyTM.Quantity() - 1 Loop // loop through rows For ColumnCount = 0 By MyTM.Columns.Quantity() - 1 Loop // nested loop through columns // get the cell value (from the current row and the current columns) CellValue = MyTR[RowCount][ColumnCount]; // display the row number, column number and cell value Report("Line #" + RowCount + "column #" + ColumnCount + " = " + CellValue); EndCycle; EndCycle;

The following will be displayed on the screen:

Line #0 column #0 = Chapaev Line #0 column #1 = Vasily Line #0 column #2 = Ivanovich Line #1 column #0 = Dzerzhinsky Line #1 column #1 = Felix Line #1 column #2 = Edmundovich Line # 2 column No. 0 = Kotovsky Line No. 2 column No. 1 = Grigory Line No. 2 column No. 2 = Ivanovich

With the help of two loops, one of which is nested in the other, we displayed the values ​​of all columns from all rows of the 1C value table. In this case, we did not use the names of the columns, but referred to the columns and rows by their indices. For better understanding, pay attention to the comments inside the example.

In conclusion, I propose to slightly change our example so that instead of column numbers, it displays their names on the screen. And in addition I will make a more presentable design for displaying content on the screen.

For RowCount = 0 By MyTR.Quantity() - 1 Loop // loop through rows Report(" ======= Row # " + RowCount + " ======="); To report(" "); // line feed (insert empty line) For ColumnCount = 0 By MyTR.Columns.Quantity() - 1 Loop // nested loop through columns // get the cell value (from the current row and current column) CellValue = MyTR[RowCount][ ColumnCount]; // get the name of the column ColumnName = MyTR.Columns[ColumnCount].Name; // display the column name and cell value Report(ColumnName + ": " + CellValue); EndCycle; To report(" "); // newline (insert empty line) EndCycle;

Now, on our screen, the information began to look more representative:

Line No. 0 ======= Last name: Chapaev First name: Vasily Middle name: Ivanovich ======= Line No. 1 ======= Last name: Dzerzhinsky First name: Felix Middle name: Edmundovich ===== == Line No. 2 ======= Surname: Kotovsky First name: Grigory Patronymic: Ivanovich

Yes, I almost forgot. When using two operators [...][...] in a row, we can pass the name of this column instead of the column index: ValueTable[RowIndex][ColumnName]

For RowCount = 0 By MyTR.Quantity() - 1 Loop // loop through rows Report(" ======= Row # " + RowCount + " ======="); To report(" "); // line feed (inserting an empty line) For ColumnCount = 0 By MyTR.Columns.Quantity() - 1 Loop // nested loop through columns ColumnName = MyTR.Columns[ColumnCount].Name; // get the column nameCellValue = MyTR[RowCount][ColumnName]; //

Pay attention to the line marked with an arrow ". In this line, instead of the index of the current column, we pass the name of the current column to the argument in square brackets[...] The result will be the same.

And now, the last in this article.

CORRECT receipt of all data of the table of values ​​1C, using cycles to iterate over the collection of rows and the collection of columns

For Each CurrentRow From MyTR Loop // cycle through the collection of strings Report(" ======= Line # " + MyTR.Index(CurrentRow) + " ======="); To report(" "); For Each CurrentColumn From MyTR.Columns Loop // nested loop through the collection of columns ColumnName = CurrentColumn.Name; // get the column nameCellValue = CurrentRow[ColumnName]; // get cell value BY column NAME Report(ColumnName + ": " + CellValue); // display the column name and cell value EndCycle; To report(" "); EndCycle;

In the example, two loops were used. The column collection loop is nested inside the row loop. If you have dealt with the examples above and read the previous articles, then you will have no difficulty in understanding how this example works.

Finally, I'll keep the number of lines of code in our last example as short as possible by eliminating the use of intermediate variables. We will get a sample of "industrial code" that is used in real tasks.

This should only be done when you have a good understanding of what you are doing. If the code is very complex, then it is acceptable to leave intermediate variables to make it easier to understand your own code later. Also, any code must be at least minimally commented, so that after some time it will be easier to understand the texts of the program.

For Each CurrentRow From MyTR Loop // loop through the lines Report(" ======= Line # " + MyTR.Index(CurrentRow) + " =======" + Symbols.PS); For Each CurrentColumn From MyTr.Columns Loop // iterate over columns Report(CurrentColumn.Name + ": " + CurrentRow[CurrentColumn.Name]); EndCycle; To report(" "); EndCycle;

The output on the screen has not changed, it remains the same as in the previous example:

2-WEEK COURSE

"PROGRAMMING in 1C FOR BEGINNERS"

The course will be emailed to you. Become a programmer by completing step-by-step tasks.

All you need to participate is a computer and internet.

Free access to the course:

sp-force-hide ( display: none;).sp-form ( display: block; background: #eff2f4; padding: 5px; width: 270px; max-width: 100%; border-radius: 0px; -moz-border -radius: 0px; -webkit-border-radius: 0px; font-family: Arial, "Helvetica Neue", sans-serif; background-repeat: no-repeat; background-position: center; background-size: auto;) .sp-form input ( display: inline-block; opacity: 1; visibility: visible;).sp-form .sp-form-fields-wrapper ( margin: 0 auto; width: 260px;).sp-form .sp -form-control ( background: #ffffff; border-color: #cccccc; border-style: solid; border-width: 1px; font-size: 15px; padding-left: 8.75px; padding-right: 8.75px; border -radius: 4px; -moz-border-radius: 4px; -webkit-border-radius: 4px; height: 35px; width: 100%;).sp-form .sp-field label ( color: #444444; font- size: 13px; font-style: normal; font-weight: bold;).sp-form .sp-button ( border-radius: 4px; -moz-border-radius: 4px; -webkit-border-radius: 4px; background-color: #f4394c; color: #ffffff; width: 100%; font-weig ht: 700; font-style: normal font-family: Arial, "Helvetica Neue", sans-serif; box-shadow: none -moz-box-shadow: none; -webkit-box-shadow: none; background: linear-gradient(to top, #e30d22 , #f77380);).sp-form .sp-button-container ( text-align: center; width: auto;)