Имя: Пароль:
1C
1C 7.7
v7: перебор всех дат и поиск в таблице значений
0 PiotrLoginov
 
29.11.12
00:18
Здравствуйте всем. Сформирована ТаблицаЗначений (есть колонка "Дата"). Необходимо перебрать даты определенного периода и для каждого дня выбрать те строки из ТаблицыЗначений, в которых "Дата" - этот день (если, конечно, таковые имеются).

Проще говоря для первого числа вынимаем из таблицы все строки, где в колонке Дата - 1, для второго числа - все со значением 2 и т.д. Подскажите, пожалуйста, на какие методы языка опереться.
1 Нуф-Нуф
 
29.11.12
00:20
Нихера не понял
2 PiotrLoginov
 
29.11.12
00:21
Как будет правильнее - отсортировать таблицу по колонке Дата и затем в переборе проверять каждую новую строку на предмет увеличения значения даты или же перебирать массив дат и для каждой даты искать в ТаблицеЗначений строки с нужным значением?
3 Darky
 
29.11.12
00:21
Откуда ТЗ сформирована? Модет проще при заполнении таблицы накладывать условие на период?
4 H A D G E H O G s
 
29.11.12
00:23
Груды хлама, снопы света
Полусонные глаза
Не хватило до рассвета
Где-то 22 часа

Было холодно и тихо,
Мысли медленно ушли
По стене и по паркету
Потекли мои мозги
5 szhukov
 
29.11.12
00:23
(2) Если нужны все данные из таблицы, то быстрее, наверное, будет перебор со сменой даты.
Если данные из таблицы нужны не все, а интересует какая-то часть, то лучше отбором по нужным строкам (НайтиСтроки).
Еще вариант - запрос, таблицу в запрос и все что угодно...
6 PiotrLoginov
 
29.11.12
00:25
(3) ТЗ сформирована из справочника с периодическим реквизитом. По формированию ТЗ вопросов нет.

"проще при заполнении таблицы накладывать условие на период?" Гм... неужели перебор дат в 1С настолько сложен?

(4) сильные строки. В данный момент я в порядке.. в сон не клонит. Помогите лучше советом; уверен, для Вас вопрос яйца выеденного не стоит.
7 PiotrLoginov
 
29.11.12
00:28
(5) "Если данные из таблицы нужны не все..." нет-нет, в итоге нужны все строки. Вот только надо их выбирать не все сразу, а сначала те, где дата - начало периода (если такие есть), затем те, где дата - начало периода + 1 и т.д.
8 szhukov
 
29.11.12
00:29
(7) Отсортируй и перебери
9 France
 
29.11.12
00:38
определи для даты день..
10 PiotrLoginov
 
29.11.12
00:45
(8) Тогда начину так:

Значения.Сортировать("Дата+");
НачалоПериода = "01.11.2012";
Значения.ВыбратьСтроки();
Пока Значения.ПолучитьСтроку() = 1 Цикл
   Если Значения.ТекущаяСтрока().Дата = НачалоПериода Тогда
...


Что-то не выходит каменный цветок ... :(
11 PiotrLoginov
 
29.11.12
00:46
*начну
12 France
 
29.11.12
00:49
можно начать с исходной задачи..
и, для развлекухи проверь, с ТЗ Дата или Дата+время.
и, самое правильное - научи себя запросам - в 8.2 их можно везде и всегда использовать... и нужно..
13 PiotrLoginov
 
29.11.12
00:49
Если перебирать отсортированную таблицу, то надо при получении новой строки как-то определять, новая там дата или прежняя... и если новая, то на сколько дней она сменилась.

Если честно, я надеялся, что в 1С как-то можно тупо перебрать все даты определенного периода и для каждой даты проверить наличие подходящих строк в ТаблицеЗначений.
14 PiotrLoginov
 
29.11.12
00:50
(12) В данном случае пишу код для 7.7
15 PiotrLoginov
 
29.11.12
00:51
Гм.. странно, вроде создавал тему в v7 ....  Капец.
16 PiotrLoginov
 
29.11.12
00:54
Сори, господа, помогите, пожалуйста, с поправкой на язык седьмой версии, а завтра я попытаюсь найти модератора с правами переноса веток.
17 PiotrLoginov
 
29.11.12
01:17
Сейчас набросаю код использования сортированной таблицы поконкретней.

Цель будет - создание табличных частей из строк с одниаковой датой. Мне это понадобится потом для программного создания документов с табличными частями.. Ну не суть. Итак:
18 PiotrLoginov
 
29.11.12
01:23
РЕЗУЛЬТАТЫ = СоздатьОбъект("ТаблицаЗначений");
РЕЗУЛЬТАТЫ.НоваяКолонка("Период","Дата",,,,);
РЕЗУЛЬТАТЫ.НоваяКолонка("ТаблЧасть");


Значения.Сортировать("Дата+");
НачалоПериода = "01.11.2012";
Значения.ВыбратьСтроки();
//для начала используем значения для одного дня
РЕЗУЛЬТАТЫ.НоваяСтрока();
РЕЗУЛЬТАТЫ.Период = Начало Периода;
Пока Значения.ПолучитьСтроку() = 1 Цикл
   ТабличнаяЧасть = СоздатьОбъект("ТаблицаЗначений");
   ТабличнаяЧасть.НоваяКолонка("Результат1");
   ТабличнаяЧасть.НоваяКолонка("Результат2");
   Если Значения.ТекущаяСтрока().Дата = НачалоПериода Тогда
       ТабличнаяЧасть.НоваяСтрока();
       ТабличнаяЧасть.Результат1 = Значения.ТекущаяСтрока().НекийРеквизит;
       ТабличнаяЧасть.Результат2 = Значения.ТекущаяСтрока().ДругойРеквизит;
   КонецЕсли;
РЕЗУЛЬТАТЫ.ТаблЧасть = ТабличнаяЧасть;
КонецЦикла;

Ну вот, я получил для одного дня (одной даты) одну строку результирующей таблицы со вложенной табличной частью. А как получить такие строки для остальных дней периода?
19 France
 
29.11.12
01:42
(15) правлю раздел
20 PiotrLoginov
 
29.11.12
02:02
(19) спасибо... у меня тем временем кажется формируется решение... как всегда простое до безобразия... или я ошибаюсь...
21 Ganiev
 
29.11.12
08:29
Можно попробовать так, если я все правильно понял!
ТзДата = СоздатьОбъект(ТаблицаЗначений);
Тз.выгрузить(ТзДата,"Дата");
ТзДата.Свернуть("Дата",);
ТзДата.выбратьстроки();
Пока ТзДата.ПолучитьСтроку() = 1 Цикл
Тз.выбратьстроки();
Пока Тз.получитьстроку() = 1 Цикл
  Если ТзДата.дата = Тз.дата Тогда
     ///Что там тебе нужно???
  КонецЕСли;
КонецЦикла;
КонецЦикла;
22 Voronve
 
29.11.12
08:55
(18) Собстна метода 2, первый - поиск в плоской таблице нужной даты и выборка строк пока дата не кончиться или не кончиться таблица. Второй (ты правильно ухватил идею) - превратить плоскую таблицу в двумерную (табица в таблице).

Пример 1 (плоская таблица):

НужнаяДата = '01.02.03';
ТЗ.Сортировать("Дата+");

Переменная = 0;
ТЗ.НайтиЗначение(НужнаяДата, Переменная, "Дата");

Если Переменная <> 0 Тогда
Пока Переменная <= ТЗ.КоличествоСтрок() Цикл
Если ТЗ.ПолучитьЗначение(Переменная, "Дата") <> НужнаяДата Тогда Прервать; КонецЕсли;
ТЗ.ПолучитьСтрокуПоНомеру(Переменная);
....
твои телодвижения
...
Переменная = Переменная + 1;
КонецЦикла;
КонецЕсли;


Пример 2 (таблица в таблице):
ТЗ = СоздатьОбъект("ТаблицаЗначений");
ТЗ.НоваяКолонка("Дата");
ТЗ.НоваяКолонка("ТЗДанные");

<ТвояТаблица>.ВыбратьСтроки();
Пока <ТвояТаблица>.ПолучитьСтроку() = 1 Цикл
Переменная = 0;
Если ТЗ.НайтиЗначение(<ТвояТаблица>.Дата, Переменная, "Дата") = 0 Тогда
ТЗ.НоваяСтрока();
ТЗ.Дата = <ТвояТаблица>.Дата;
ТЗ.УстановитьЗначение(ТЗ.НомерСтроки, "ТЗДанные", СоздатьОбъект("ТаблицаЗначений"));

ТЗПеременная = ТЗ.ТЗДанные;
Иначе
ТЗ.ПолучитьСтрокуПоНомеру(Переменная);
ТЗПеременная = ТЗ.ТЗДанные;
КонецЕсли;

ТЗПеременная.НоваяСтрока();
...
твои телодвижения
....
КонецЦикла;
23 PiotrLoginov
 
29.11.12
17:04
Вчера после завершения работы уже не хватило сил отписаться о найденном решении. В конечном итоге вопрос решается, имхо, организацией цикла перебора искомых строк внутри цикла перебора дат.

(21) Спасибо Большое. Создать вспомогательную таблицу, свернуть ее и организовать цикл с перебором ее строк - просто гениальная идея, ибо все гениальное просто. Вот и я вчера не мудрствуя лукаво попросту перебрал все даты требуемого периода:

День = '01.11.2012';
Пока НЕ (День = '30.11.2012') Цикл
//здесь ищем в таблице все строки с текущей датой и делаем с ними все, что хотим, т.е. внутри цикла перебора дат организуем цикл перебора
День = День + 1;
КонецЦикла;

Как и подозревалось, вопрос яйца выеденного не стоил, и все же для меня это было несколько потерянных часов :(

...................................
Вопрос решен, но да здравствуют новые вопросы. В основном благодаря (22). Не знаю, стоит ли в них копаться...
Честно говоря, мне не удалось до конца въехать в смысл предложенного в первом примере, так как я плохо представляю себе работу метода НайтиЗначение() . В третий параметр метод возвращает номер найденной строки? А если найденных строк несколько? Тогда видимо для первой найденной строки? Т.е. только для одной? Гм...  как, для начала, организован перебор дат? Мне показалось так мы получим данные только для одной даты - '01.02.03' ...

__________

Во втором примере, видимо, предлагается заполнить ТЗ в рамках одного цикла (а не цикла внутри цикла) перебора строк <ТвояТаблица>. Это конечно невероятно круто... Если бы я еще понимал, как этим пользоваться :D
Просто скопировать код нет смысла - мне надо его модифицировать под свои нужды... Ну вот:

...
Переменная = 0;
Если ТЗ.НайтиЗначение(<ТвояТаблица>.Дата, Переменная, "Дата") = 0 Тогда
// в этой строке метод дает нам номер строки с текущей датой в ТЗ ? Ну а если там таких строк уже записано несколько?
ТЗ.НоваяСтрока();
ТЗ.Дата = <ТвояТаблица>.Дата;
ТЗ.УстановитьЗначение(ТЗ.НомерСтроки, "ТЗДанные", СоздатьОбъект("ТаблицаЗначений"));
//здесь в создаваемой строке указывается, что в ячейке колонки "ТЗДанные" будет таблица. Но как она потом заполняется? Я привык, что сначала таблица формируется, а потом уже "запихивается" в ячейку

ТЗПеременная = ТЗ.ТЗДанные;
Иначе
ТЗ.ПолучитьСтрокуПоНомеру(Переменная);
ТЗПеременная = ТЗ.ТЗДанные;
КонецЕсли;

ТЗПеременная.НоваяСтрока();
//здесь в таблице ТЗПеременная, которой присвоены значения ячейки ТЗДанные (но ячейка ведь пока пуста?) предлагается создать новую строку и делать что заблагорассудится... так мы в итоге куда результат наших трудов "складываем"? В ТЗ ? Тогда зачем сейчас заполняем ТЗПеременная ? Позже ее содержимое использовано в цикле ведь не будет
...