Имя: Пароль:
1C
 
Как выгрузить табличное поле в таблицу значений?
0 askharlov
 
20.01.11
10:12
Суть:
Есть документ с табличным полем в форме документа.
Необходимо выгрузить табличное поле в таблицу значений для дальнейшей обработки.
Табличное поле связано с табличной частью документа, но состав его строк отличается от состава строк табличной части документа в связи с:
1. Наличием вычисляемых полей
2. Установленным отбором

Колонки выгрузить могу через ТаблПоле.Колонки и обойти циклом "Для каждого". А как выгрузить строки?!?!?!?!
Табличную часть документа тоже выгрузить могу. Но она, как написал, отличается от табличного поля составом строк и колонок.

Заранее благодарю
1 askharlov
 
25.01.11
13:05
Господа!
Задача все еще актуальна? есть идеи?
2 mikecool
 
25.01.11
13:13
Табличная часть (Tabular section)
Выгрузить (Unload)
Вариант синтаксиса: Выгрузить колонки

Синтаксис:

Выгрузить(<Строки>, <Колонки>)
3 73
 
25.01.11
13:21
Вычисляемые колонки вычислить.
Отобранные строки выгрузить Построителем.

//Построителем
Построитель = Новый ПостроительЗапроса;
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабличнаяЧасть);
//Здесь отбор если нужно
Для Каждого ЭлементОтбора из ЭлементыФормы.ТабличнаяЧасть.ОтборСтрок Цикл
   ЗаполнитьЗначенияСвойств(Построитель.Отбор.Добавить(ЭлементОтбора.Имя), ЭлементОтбора);
КонецЦикла;
ТЗ = Построитель.Результат.Выгрузить();
4 НЕА123
 
25.01.11
13:31
СП
ОформлениеСтроки()
?
5 askharlov
 
28.01.11
17:02
(2) mikecool, ТабличнаяЧасть.Вsuhepbnm - это для табличной части (ТЧ) документа, а не для ТабличногоПоля. Табличное поле, конечно связано с ТЧ документа, но в нем (в табличном поле) присутствуют вычисляемые колонки, которых в ТЧ документа нет. В результате приходится или добавлять соответствующие реквизиты в ТЧ документа (не совсем красиво) или пересчитывать колонки (потеря производительности). На данный момент решил вопрос через добавление доп.реквизитов в ТЧ документа.
(3) 73, Решение реальное, но дополнительный пересчет - это потеря производительности. Предпочел добавить доп.реквизиты в табличную часть документа, как написал выше.
6 НЕА123
 
28.01.11
17:10
типа так(не проверял):

Для каждого Стр ИЗ ТЧ Цикл
  Если ЭлементыФормы.ТабПоле.ПРоверитьСтроку(Стр) Тогда
        СтрокаТП = ЭлементыФормы.ТабПоле.ОформлениеСтроки(Стр)
//Добавляем новую строку в ТЗ
//и заполняем  значениями из СтрокаТП.Ячейки.НужнаяЯчейка1.Значение;    
  КонецЕсли;
КонецЦикла
7 askharlov
 
28.01.11
17:12
(4) НЕА123, что такое "СП"?
ОформлениеСтроки() : да, у табличного поля есть такой метод, но его синтаксис ТабличноеПоле.ОформлениеСтроки(<Строка>).
А как программно перебрать все строки табличного поля, чтоб получить этот параметр <Строка>?
8 askharlov
 
28.01.11
17:16
(6) Если не проверял, то могу рассказать:
1. про метод "ОформлениеСтроки уже написал выше.
2. "ОформлениЕСтроки" появляется в событии "ПриВыводеСтроки", но там оформление только одной строки
3. В событии "ПриПолученииДанных" появляется "ОформлениЯСтроки" (коллекция элементов "ОформлениЕСтроки"), но эта коллекция содержит только те элементы, которые в данный момент выведены на экран.

Но все равно спасибо за ответ.
9 askharlov
 
28.01.11
17:21
Резюме: получается вроде как выгрузка ТабличногоПоля в 1С не предусмотрена, вероятно так как обычно оно жестко связано с табличной частью документа, а рассчетные поля обычно, если они в Табл.поле и присутствуют, то все они равно одноразовые и никому повторно не нужны или расчеты простые и можно пересчитать повторно.
10 НЕА123
 
28.01.11
17:23
нет слов...
у меня уже вторая ветка сегодня...
автор получает ответ, и говорит: НЕТ НЕПРАВДА!(ничего не читая и не проверяя).
ладно, жду.
как и в ветке v8: Критерии отбора - как прочитать состав? пару часов.
11 73
 
28.01.11
17:27
(8) Почитай про ПроверитьСтроку() и МЕТОД ОформлениеСтроки(), который не имеет общего с созвучными параметрами процедур ПриВыводеСтроки/ПриПолученииДанных.
В (6) реальный алгоритм: Перебирается не поле, а ТЧ. Проверяется соответствие строки отбору и если да - запрашивается её(этой строки) - ОформлениеСтроки().

ЗЫ. Имхо, перебирать всю ТЧ может оказаться накладнее, чем метод (3).
12 НЕА123
 
28.01.11
17:36
(11)
>ЗЫ. Имхо, перебирать всю ТЧ может оказаться накладнее, чем метод (3).
не могу не согласиться.
положительно в (6) то, что отсутствуют обращения к БД, ну и не надо разбираться с алгоритмами расчета колонок.
пусть автор выбирает (3) или (6), программист вроде...
13 Lisica
 
04.02.11
14:53
Вычисляемые колонки вычислить.
Отобранные строки выгрузить Построителем.

//Построителем
Построитель = Новый ПостроительЗапроса;
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабличнаяЧасть);
//Здесь отбор если нужно
Для Каждого ЭлементОтбора из ЭлементыФормы.ТабличнаяЧасть.ОтборСтрок Цикл
   ЗаполнитьЗначенияСвойств(Построитель.Отбор.Добавить(ЭлементОтбора.Имя), ЭлементОтбора);
КонецЦикла;
ТЗ = Построитель.Результат.Выгрузить();


73!!!!!!!!!!!!!
СПАСИБО ОГРОМНОЕ ЗА ЭТО!!!!!!!!!!!
ОЧЕНЬ-ОЧЕНЬ ПОМОГЛО!!!!!!!!!!
14 askharlov
 
10.02.11
19:08
НЕА123 (10)
Если ты прав, то извини. Может я где недоразобрался. Сейчас вопрос мною решен, так что потерял актуальность. А времени, естественно на все не хватает:-)

Спасибо всем за ответы.

П.С.:
Я решил следующим образом:
1. В табличную часть документа добавил как реквизиты все свои расчетные поля). По здравому размышлению это оказалось даже полезным, один из моментов: так как расчетные поля идут также в печатную форму, и документ, сохраненный в базе всегда соответствует тому, который распечатан. А пересчет данных по документу организовал в виде отдельной кнопки, т.о. автоматом 1С не пересчитывает.
2. Когда необходимо обработать те строки, которые в данный момент выведены на экран, с учетом установленных отборов, то считываю данные из табличной части документа методом "НайтиСтроки", в который передаю структуру с параметрами установленного отбора.
2.1. Для формирования структуры отбора, которая передается в НайтиСтроки написал свою функцию обхода ЭлементовОтбора.

Все.
Решение меня на данном этапе устраивает, так что интерес касательно других методов обхода строк табличного поля формы на данный момент только спортивный.
Будет свободное время - перечитаю последние ответы, попробую.

Спасибо всем за ответы.
15 NewNick
 
10.02.11
19:18
топик стартер только только перешел с каких нить си или папаскакаля(он же дельфи) на 1С ?)
ну очень похоже )
если так то совет, оценки эффективности методов тех или иных решений оценивать внимательно.
"дополнительный пересчет" в данном случае не является критичным как потеря производительности. так как используется при интерфейсе.
16 НЕА123
 
11.02.11
08:50
(14).2
НайтиСтроки() - это только для отбора на равенство.
17 askharlov
 
12.02.11
11:45
NewNick, (15) спасибо за совет. Приму к сведению
НЕА123 (16) Абсолютно верно. Но смотри (14) 2.1. - Извини написал, пожалуй кратко. Если расшифровать, то все выглядит так:
(14) 2.1. Методом НайтиСтроки получаю из ТЧ все строки для отборов с ВидСравнения.Равно
2.2. Обхожу все строки полученного массива найденных строк и обхожу все отборы с Использование = Истина.
2.3. На основе ВидовСравнения формирую соответствующие условия сравнения
2.4. Строки массива найденных строк, которые не соответствуют условиям отбора, помечаю на удаление.
2.5. Удаляю помеченные на удаление строки.
Все
18 askharlov
 
12.02.11
11:50
Вот сама функция (сложного ничего, но все ж может кому сэкономит полчаса времени):
// имена отборов должны совпадать с колонками табличной части
//  не обрабатываются отборы с видом сравнения "Иерархия"
//  ТекущийЭлементФормы - ТабличноеПоле, в котором анализируются отборы
//  ТабличнаяЧасть - табличная часть документа или таблица значений, с которой связан ТекущийЭлементФормы
//  Функция возвращает массив строк табличной части, удовлетворяющих установленным отборам

Функция ПолучитьМассивСтрокТабличнойЧастиПоТекущимОтборам(ТабличнаяЧасть, ТекущийЭлементФормы)
                                                       
   СтруктураОтбора = Новый Структура;
   
   // заполним СтруктуруОтбора согласно отборам с ВидСравнения.Равно
   Для каждого ЭлементОтбора из ТекущийЭлементФормы.ОтборСтрок Цикл
       
       Если ЭлементОтбора.Использование И  ЭлементОтбора.ВидСравнения = ВидСравнения.Равно Тогда
           
           СтруктураОтбора.Вставить(ЭлементОтбора.Имя, ЭлементОтбора.Значение);
           
       КонецЕсли;
       
   КонецЦикла;
   
   // получим массив строк табличной части, соответствующих отборам с ВидСравнения.Равно
   МассивНайденныхСтрок = ТабличнаяЧасть.НайтиСтроки(СтруктураОтбора);
   
   // объявим массив, в который будем записывать номера строк МассивНайденныхСтрок, которые не удовлетворяют отбору
   МассивНомераУдаляемыхСтрок = Новый Массив;    
   
   // Обходим остальные отборы с Не ВидСравнения.Равно и исключаем из массива строки, которые не устраивают отбору
   Для каждого Строка из МассивНайденныхСтрок Цикл
       
       УдалитьСтроку = Ложь;
       
       Для каждого ЭлементОтбора из ТекущийЭлементФормы.ОтборСтрок Цикл
           
           // прекращаем обработку текущего элемента, если не установлено его использование
           Если Не ЭлементОтбора.Использование Тогда Продолжить КонецЕсли;
           
           //Обработаем ВидСравнения.НеРавно
           Если ЭлементОтбора.ВидСравнения = ВидСравнения.НеРавно Тогда
               Если Не(Строка[ЭлементОтбора.Имя] <> ЭлементОтбора.Значение) Тогда
                   УдалитьСтроку = Истина;
                   Перейти ~ПолучитьМассивСтрокТабличнойЧастиПоТекущимОтборамКонецЦикла;
               КонецЕсли;
           КонецЕсли;    
           
            //Обработаем  ВидСравнения.ВСписке
            Если ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке Тогда
               
                ЭлементНайденВСписке = Ложь;
               
               Для каждого ЭлементСписка из ЭлементОтбора.Значение Цикл
                   Если Строка[ЭлементОтбора.Имя] = ЭлементСписка.Значение Тогда
                       ЭлементНайденВСписке = Истина;
                       Прервать;
                   КонецЕсли;
               КонецЦикла;
               
               Если Не ЭлементНайденВСписке Тогда
                   УдалитьСтроку = Истина;
                   Перейти ~ПолучитьМассивСтрокТабличнойЧастиПоТекущимОтборамКонецЦикла;
               КонецЕсли;
               
           КонецЕсли;    
       
            //Обработаем  ВидСравнения.НеВСписке
            Если ЭлементОтбора.ВидСравнения = ВидСравнения.НеВСписке Тогда
               
                ЭлементНайденВСписке = Ложь;
               
               Для каждого ЭлементСписка из ЭлементОтбора.Значение Цикл
                   Если Строка[ЭлементОтбора.Имя] = ЭлементСписка.Значение Тогда
                       ЭлементНайденВСписке = Истина;
                       Прервать;
                   КонецЕсли;
               КонецЦикла;
               
               Если ЭлементНайденВСписке Тогда
                   УдалитьСтроку = Истина;
                   Перейти ~ПолучитьМассивСтрокТабличнойЧастиПоТекущимОтборамКонецЦикла;
               КонецЕсли;
               
           КонецЕсли;    
           
            //Обработаем ВидСравнения.Содержит
            Если ЭлементОтбора.ВидСравнения = ВидСравнения.Содержит Тогда
               Если Не(Найти(Строка[ЭлементОтбора.Имя], ЭлементОтбора.Значение) > 0) Тогда
                   УдалитьСтроку = Истина;
                   Перейти ~ПолучитьМассивСтрокТабличнойЧастиПоТекущимОтборамКонецЦикла;
               КонецЕсли;
           КонецЕсли;
           
            //Обработаем ВидСравнения.НеСодержит
            Если ЭлементОтбора.ВидСравнения = ВидСравнения.НеСодержит Тогда
               Если Не (Найти(Строка[ЭлементОтбора.Имя], ЭлементОтбора.Значение) = 0) Тогда
                   УдалитьСтроку = Истина;
                   Перейти ~ПолучитьМассивСтрокТабличнойЧастиПоТекущимОтборамКонецЦикла;
               КонецЕсли;
           КонецЕсли;
           
            //Обработаем ВидСравнения.Меньше
           Если ЭлементОтбора.ВидСравнения = ВидСравнения.Меньше Тогда
               Если Не (Строка[ЭлементОтбора.Имя] < ЭлементОтбора.Значение) Тогда
                   УдалитьСтроку = Истина;
                   Перейти ~ПолучитьМассивСтрокТабличнойЧастиПоТекущимОтборамКонецЦикла;
               КонецЕсли;
           КонецЕсли;    
           
            //Обработаем ВидСравнения.МеньшеИлиРавно
           Если ЭлементОтбора.ВидСравнения = ВидСравнения.МеньшеИлиРавно Тогда
               Если Не (Строка[ЭлементОтбора.Имя] <= ЭлементОтбора.Значение) Тогда
                   УдалитьСтроку = Истина;
                   Перейти ~ПолучитьМассивСтрокТабличнойЧастиПоТекущимОтборамКонецЦикла;
               КонецЕсли;
           КонецЕсли;    
           
            //Обработаем ВидСравнения.Больше
           Если ЭлементОтбора.ВидСравнения = ВидСравнения.Больше Тогда
               Если Не (Строка[ЭлементОтбора.Имя] > ЭлементОтбора.Значение) Тогда
                   УдалитьСтроку = Истина;
                   Перейти ~ПолучитьМассивСтрокТабличнойЧастиПоТекущимОтборамКонецЦикла;
               КонецЕсли;
           КонецЕсли;    
           
            //Обработаем ВидСравнения.БольшеИлиРавно
           Если ЭлементОтбора.ВидСравнения = ВидСравнения.БольшеИлиРавно Тогда
               Если Не (Строка[ЭлементОтбора.Имя] >= ЭлементОтбора.Значение) Тогда
                   УдалитьСтроку = Истина;
                   Перейти ~ПолучитьМассивСтрокТабличнойЧастиПоТекущимОтборамКонецЦикла;
               КонецЕсли;
           КонецЕсли;    
           
            //Обработаем ВидСравнения.Интервал
           Если ЭлементОтбора.ВидСравнения = ВидСравнения.Интервал Тогда
               Если Не (Строка[ЭлементОтбора.Имя] > ЭлементОтбора.ЗначениеС
                        И Строка[ЭлементОтбора.Имя] < ЭлементОтбора.ЗначениеПо) Тогда
                   УдалитьСтроку = Истина;    
                   Перейти ~ПолучитьМассивСтрокТабличнойЧастиПоТекущимОтборамКонецЦикла;
               КонецЕсли;
           КонецЕсли;    
           
            //Обработаем ВидСравнения.ИнтервалВключаяГраницы
           Если ЭлементОтбора.ВидСравнения = ВидСравнения.ИнтервалВключаяГраницы Тогда
               Если Не (Строка[ЭлементОтбора.Имя] >= ЭлементОтбора.ЗначениеС
                        И Строка[ЭлементОтбора.Имя] <= ЭлементОтбора.ЗначениеПо) Тогда
                   УдалитьСтроку = Истина;    
                   Перейти ~ПолучитьМассивСтрокТабличнойЧастиПоТекущимОтборамКонецЦикла;
               КонецЕсли;
           КонецЕсли;    
           
            //Обработаем ВидСравнения.ИнтервалВключаяНачало
           Если ЭлементОтбора.ВидСравнения = ВидСравнения.ИнтервалВключаяНачало Тогда
               Если Не (Строка[ЭлементОтбора.Имя] >= ЭлементОтбора.ЗначениеС
                        И Строка[ЭлементОтбора.Имя] < ЭлементОтбора.ЗначениеПо) Тогда
                   УдалитьСтроку = Истина;    
                   Перейти ~ПолучитьМассивСтрокТабличнойЧастиПоТекущимОтборамКонецЦикла;
               КонецЕсли;
           КонецЕсли;    
           
            //Обработаем ВидСравнения.ИнтервалВключаяОкончание
           Если ЭлементОтбора.ВидСравнения = ВидСравнения.ИнтервалВключаяОкончание Тогда
               Если Не (Строка[ЭлементОтбора.Имя] > ЭлементОтбора.ЗначениеС
                        И Строка[ЭлементОтбора.Имя] <= ЭлементОтбора.ЗначениеПо) Тогда
                   УдалитьСтроку = Истина;    
                   Перейти ~ПолучитьМассивСтрокТабличнойЧастиПоТекущимОтборамКонецЦикла;
               КонецЕсли;
           КонецЕсли;    
           
       КонецЦикла;
       
       ~ПолучитьМассивСтрокТабличнойЧастиПоТекущимОтборамКонецЦикла:
       
       // удаляем текущую строку из массива, если она не удовлетворила одному из условий
       Если УдалитьСтроку Тогда
           
           МассивНомераУдаляемыхСтрок.Добавить(Строка.НомерСтроки);
           
       КонецЕсли;
       
   КонецЦикла;
   
   // Удалим из МассивНайденныхСтрок строки, номера которых занесены в массив МассивНомеровСтрокДляУдаления
   Для Индекс = 0 По МассивНайденныхСтрок.Количество() Цикл
       
       // условие необходимо, так как в цикле происходит удаление элементов массива
       Если Индекс > (МассивНайденныхСтрок.Количество() - 1) Тогда прервать КонецЕсли;
       
       ТекущаяСтрока = МассивНайденныхСтрок[Индекс];
       
       // Если номер текущей строки массива МассивНайденныхСтрок присутствует в массиве
       //  МассивНомераУдаляемыхСтрок, то удаляем эту строку
       Если МассивНомераУдаляемыхСтрок.Найти(ТекущаяСтрока.НомерСтроки) <> Неопределено Тогда
           МассивНайденныхСтрок.Удалить(Индекс);
           // так как произошло удаление строки, то декрементируем индекс чтоб не произошло перескакивание через один элемент массива
           Индекс = Индекс - 1;
       КонецЕсли;
   КонецЦикла;
   
   Возврат МассивНайденныхСтрок;

КонецФункции  // ПолучитьМассивСтрокТабличнойЧастиПоТекущимОтборам()
Выдавать глобальные идеи — это удовольствие; искать сволочные маленькие ошибки — вот настоящая работа. Фредерик Брукс-младший