|
|
|
Как сравнить две версии регистра сведений | ☑ | ||
|---|---|---|---|---|
|
0
Гений 1С
гуру
09.01.07
✎
18:33
|
Короче, нужно отследить изменения в регистре сведений.
Итак, есть в одной таблице значений колонки: Изм1, Изм2,...ИзмН Рес1, ...РесМ Это начальное состояние регистра сведений. В другой таблице значений такие же колонки: Изм1, Изм2,...ИзмН Рес1, ...РесМ Это конечное состояние регистра сведений. Нужно получить результирующую таблицу: Изм1, Изм2,...ИзмН Рес1, ...РесМ Статус Где Статус: 0 - запись не изменилась 1 - запись изменилась -1 - запись удалилась 2 - были изменены ресурсы (желательно еще и список этих ресурсов) Кто такое делал, как подступить? |
|||
|
1
Terv
09.01.07
✎
18:35
|
чем свернуть не подходит?
|
|||
|
2
Гений 1С
гуру
09.01.07
✎
18:35
|
(1) ресурсы не числовые
|
|||
|
3
Варвар
09.01.07
✎
18:41
|
"Вывести список", и "сравнить файлы" в 1С не катит?
|
|||
|
4
Гений 1С
гуру
09.01.07
✎
18:49
|
(3) Не ручками, а программно и регулярно.. ;-) Не катят...
|
|||
|
5
Johnbay
09.01.07
✎
18:58
|
Запросом самое простое думаю
|
|||
|
6
jcage
09.01.07
✎
19:02
|
8.1 или 8.0?
|
|||
|
7
Johnbay
09.01.07
✎
19:04
|
ВЫБРАТЬ
КурсыВалют.Курс, КурсыВалют.Кратность, КурсыВалют.Период, КурсыВалют1.Валюта, КурсыВалют1.Курс КАК Курс1, КурсыВалют1.Кратность КАК Кратность1, ВЫБОР КОГДА (НЕ КурсыВалют.Курс = КурсыВалют1.Курс) ИЛИ (НЕ КурсыВалют.Кратность = КурсыВалют1.Кратность) ТОГДА "2" КОНЕЦ КАК Статус ИЗ РегистрСведений.КурсыВалют КАК КурсыВалют ПОЛНОЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют КАК КурсыВалют1 ПО КурсыВалют.Валюта = КурсыВалют1.Валюта |
|||
|
8
Johnbay
09.01.07
✎
19:04
|
Остальные статусы пропиши и все дела
|
|||
|
9
jcage
09.01.07
✎
19:05
|
(7) не хочу обидеть коллега, но мне кажется, что вы написали фигню.
|
|||
|
10
Johnbay
09.01.07
✎
19:06
|
ну вместо
ПОЛНОЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют КАК КурсыВалют1 ПО КурсыВалют.Валюта = КурсыВалют1.Валюта нада поправить на ПОЛНОЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют1 КАК КурсыВалют1 ПО КурсыВалют.Валюта = КурсыВалют1.Валюта т.е. второй регистр "КурсыВалют1" в итоге ВЫБРАТЬ КурсыВалют.Курс, КурсыВалют.Кратность, КурсыВалют.Период, КурсыВалют1.Валюта, КурсыВалют1.Курс КАК Курс1, КурсыВалют1.Кратность КАК Кратность1, ВЫБОР КОГДА (НЕ КурсыВалют.Курс = КурсыВалют1.Курс) ИЛИ (НЕ КурсыВалют.Кратность = КурсыВалют1.Кратность) ТОГДА "2" КОНЕЦ КАК Статус ИЗ РегистрСведений.КурсыВалют КАК КурсыВалют ПОЛНОЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют1 КАК КурсыВалют1 ПО КурсыВалют.Валюта = КурсыВалют1.Валюта |
|||
|
11
Гений 1С
гуру
09.01.07
✎
19:07
|
Запрос не катит, вторая ТЗ формируется не из регистра... а лишь по сути имитирует регистр.
|
|||
|
12
jcage
09.01.07
✎
19:09
|
(0) Тебе похоже просто надо сравнить две ТЗ.
Сортируй по периодам и валютам, далее обходи первую ТЗ и построчно сравнивай. |
|||
|
13
Гений 1С
гуру
09.01.07
✎
19:09
|
(12) у меня 4 регистра, надо какую-то универсальную хрень, хотя подход неплохой.
|
|||
|
14
Johnbay
09.01.07
✎
19:09
|
(11)
если все статично (формирующаяся ТЗ_2) то можно и нарисовать этот регистр, сгружать туда данные, строить запрос, удалять. |
|||
|
15
jcage
09.01.07
✎
19:14
|
(14) Я как-то пробовал использовать регистр сведений как буфер - фигня получилась. Запись в регистр - очень долгая операция по сравнению с работой с ТЗ.
(13) Так там написать универсальную процедуру легко. Просто получаешь первую строку из первой ТЗ, получаешь первую строку из второй ТЗ и сравниваешь. Тут важно замечательное свойство регистра сведений - уникальность записи по комбинации измерений (и периоду). Т.е. если ты осортируешь ТЗ по периоду и всем измерениям - то можешь со 100 % сравнить. Правда сортировка может времени дофига занять. Но зато обход будет только один. |
|||
|
16
Johnbay
09.01.07
✎
19:17
|
(15)
Смотря как писать. По одной записи - да, долго. Оптом - быстрее напорядок :) Ну в общем хозяин - барин. |
|||
|
17
asady
09.01.07
✎
19:20
|
(0) попробуй в транзакции попытку записи в РС
если будет ошибка - уникальный набор измерений уже есть - найти его легко. если ошибки нет - такого набора нет - искать нечего. |
|||
|
18
Neco
09.01.07
✎
20:50
|
Как вариант выгрузить ТЗ1 и ТЗ2 в ТЗ. Далее свернуть ТЗ по измерениям и.. ресурсам. Потом, с помощью НайтиСтроки(..) найти все строки с Изм1, Изм2,...ИзмН и проверить, если строк > 1, то ресурсы менялись. Далее можно пройтись по ресурсам и по сравнивать их и выявить какой ресурс менялся.
|
|||
|
19
Гений 1С
гуру
10.01.07
✎
12:12
|
(18) Я придумал другой способ.
Вот примерный код, пока еще не проверял, но думаю понятен ход мысли (нужно еще дебуггить): //ТЗИсх - какая таблица была //ТЗКон - какая таблица стала //Названия колонок должны совпадать //Ключи - массив ключей Функция обСравнитьПоКлючамТЗ(ТЗНач, ТЗКон, Ключи, НазваниеКолонкиРезультата="Статус") ТЗРез=Новый ТаблицаЗначений(); КолРез=Новый Массив(); //Ищем общие колонки в обоих таблицах Для Каждого Эл ИЗ ТЗНач.Колонки Цикл Если ТЗКон.Колонки.Найти(Эл.Имя)<>Неопределено Тогда КолРез.Добавить(Эл.Имя); КонецЕсли; КонецЦикла; //Добавляем эти колонки в таблицу-результат Для Каждого Эл ИЗ КолРез Цикл ТЗРез.Колонки.Добавить(Эл); КонецЦикла; //Добавляем служебные колонки ТЗРез.Колонки.Добавить("___ТЗНачИндекс"); ТЗРез.Колонки.Добавить("___ТЗКонИндекс"); ТЗРез.Колонки.Добавить("___ТЗНачКонтроль"); ТЗРез.Колонки.Добавить("___ТЗКонКонтроль"); Для Каждого Стр Из ТЗНач Цикл НовСтр=ТЗРез.Добавить(); НовСтр.___ТЗНачИндекс=ТЗНач.Индекс(Стр); НовСтр.___ТЗКонИндекс=0; Для Каждого Эл Из Ключи Цикл НовСтр[Эл]=Стр[Эл]; КонецЦикла; КонецЦикла; Для Каждого Стр Из ТЗКон Цикл НовСтр=ТЗРез.Добавить(); НовСтр.___ТЗНачИндекс=0; НовСтр.___ТЗКонИндекс=ТЗКон.Индекс(Стр); Для Каждого Эл Из Ключи Цикл НовСтр[Эл]=Стр[Эл]; КонецЦикла; КонецЦикла; ТЗРез.ЗаполнитьЗначения(1, "___ТЗНачКонтроль"); ТЗРез.ЗаполнитьЗначения(1, "___ТЗКонКонтроль"); СтрокаСвертки=""; Для Каждого Эл Из Ключи Цикл СтрокаСвертки=СтрокаСвертки+?(СтрокаСвертки="","",",")+Эл; КонецЦикла; СтрокаИтогов=""; Для Каждого Эл Из КолРез Цикл СтрокаИтогов=СтрокаИтогов+?(СтрокаИтогов="","",",")+Эл; КонецЦикла; //Сворачиваем ТЗРез.Свернуть(СтрокаСвертки, СтрокаИтогов); //Восстанавливаем общие колонки ЗнКол=Новый Массив(); Для Каждого Эл ИЗ КолРез Цикл Если ТЗРез.Колонки.Найти(Эл)=Неопределено Тогда ТЗРез.Колонки.Добавить(Эл); ЗнКол.Добавить(Эл); КонецЕсли; КонецЦикла; ТЗРез.Колонки.Добавить(НазваниеКолонкиРезультата); //Формируем таблицу результата Для Каждого Стр ИЗ ТЗРез Цикл Если Стр.___ТЗНачИндекс=0 Тогда Стр[НазваниеКолонкиРезультата]=+1; //Добавлена Для Каждого Эл ИЗ ЗнКол Цикл Зн=ТЗКон.___ТЗКонИндекс[Эл]; Стр[Эл]=Зн; КонецЦикла; ИначеЕсли Стр.___ТЗКонИндекс=0 Тогда Стр[НазваниеКолонкиРезультата]=-1; //Удалена Для Каждого Эл ИЗ ЗнКол Цикл Зн=ТЗНач.___ТЗНачИндекс[Эл]; Стр[Эл]=Зн; КонецЦикла; Иначе Р=Новый Структура(); Для Каждого Эл ИЗ ЗнКол Цикл ЗнНач=ТЗНач.___ТЗНачИндекс[Эл]; ЗнКон=ТЗКон.___ТЗКонИндекс[Эл]; Если ЗнНач<>ЗнКон Тогда Р.Вставить(Эл, ЗнНач); КонецЕсли; Стр[Эл]=ЗнКон; КонецЦикла; Стр[НазваниеКолонкиРезультата]=Р; //Структура изменений КонецЕсли; КонецЦикла; Возврат ТЗРез; КонецФункции |
|||
|
20
Гений 1С
гуру
10.01.07
✎
14:00
|
Вот окончательная отлаженная версия, юзается метод Свернуть:
//ТЗИсх - какая таблица была //ТЗКон - какая таблица стала //Названия колонок должны совпадать //Ключи - массив ключей Функция обСравнитьПоКлючамТЗ(ТЗНач, ТЗКон, Ключи, НазваниеКолонкиРезультата="Статус") ТЗРез=Новый ТаблицаЗначений(); КолРез=Новый Массив(); //Ищем общие колонки в обоих таблицах Для Каждого Эл ИЗ ТЗНач.Колонки Цикл Если ТЗКон.Колонки.Найти(Эл.Имя)<>Неопределено Тогда КолРез.Добавить(Эл.Имя); КонецЕсли; КонецЦикла; //Добавляем эти колонки в таблицу-результат Для Каждого Эл ИЗ КолРез Цикл ТЗРез.Колонки.Добавить(Эл); КонецЦикла; //Добавляем служебные колонки ТЗРез.Колонки.Добавить("___ТЗНачИндекс"); ТЗРез.Колонки.Добавить("___ТЗКонИндекс"); ТЗРез.Колонки.Добавить("___ТЗНачКонтроль"); ТЗРез.Колонки.Добавить("___ТЗКонКонтроль"); Для Каждого Стр Из ТЗНач Цикл НовСтр=ТЗРез.Добавить(); НовСтр.___ТЗНачИндекс=ТЗНач.Индекс(Стр)+1; НовСтр.___ТЗКонИндекс=0; Для Каждого Эл Из Ключи Цикл НовСтр[Эл]=Стр[Эл]; КонецЦикла; КонецЦикла; Для Каждого Стр Из ТЗКон Цикл НовСтр=ТЗРез.Добавить(); НовСтр.___ТЗНачИндекс=0; НовСтр.___ТЗКонИндекс=ТЗКон.Индекс(Стр)+1; Для Каждого Эл Из Ключи Цикл НовСтр[Эл]=Стр[Эл]; КонецЦикла; КонецЦикла; ТЗРез.ЗаполнитьЗначения(1, "___ТЗНачКонтроль"); ТЗРез.ЗаполнитьЗначения(1, "___ТЗКонКонтроль"); СтрокаСвертки=""; Для Каждого Эл Из Ключи Цикл СтрокаСвертки=СтрокаСвертки+?(СтрокаСвертки="","",",")+Эл; КонецЦикла; СтрокаИтогов="___ТЗНачИндекс,___ТЗКонИндекс,___ТЗНачКонтроль,___ТЗКонКонтроль"; //Сворачиваем ТЗРез.Свернуть(СтрокаСвертки, СтрокаИтогов); //Восстанавливаем общие колонки ЗнКол=Новый Массив(); Для Каждого Эл ИЗ КолРез Цикл Если ТЗРез.Колонки.Найти(Эл)=Неопределено Тогда ТЗРез.Колонки.Добавить(Эл); ЗнКол.Добавить(Эл); КонецЕсли; КонецЦикла; ТЗРез.Колонки.Добавить(НазваниеКолонкиРезультата); //Формируем таблицу результата Для Каждого Стр ИЗ ТЗРез Цикл Если Стр.___ТЗНачКонтроль>1 ИЛИ Стр.___ТЗКонКонтроль>1 Тогда Возврат Новый Структура("КодОшибки","ДублированиеКлюча"); ИначеЕсли Стр.___ТЗНачИндекс=0 Тогда Стр[НазваниеКолонкиРезультата]=+1; //Добавлена Для Каждого Эл ИЗ ЗнКол Цикл Зн=ТЗКон.Получить(Стр.___ТЗКонИндекс-1)[Эл]; Стр[Эл]=Зн; КонецЦикла; ИначеЕсли Стр.___ТЗКонИндекс=0 Тогда Стр[НазваниеКолонкиРезультата]=-1; //Удалена Для Каждого Эл ИЗ ЗнКол Цикл Зн=ТЗНач.Получить(Стр.___ТЗНачИндекс-1)[Эл]; Стр[Эл]=Зн; КонецЦикла; Иначе Р=Новый Структура(); Для Каждого Эл ИЗ ЗнКол Цикл ЗнНач=ТЗНач.Получить(Стр.___ТЗНачИндекс-1)[Эл]; ЗнКон=ТЗКон.Получить(Стр.___ТЗКонИндекс-1)[Эл]; Если ЗнНач<>ЗнКон Тогда Р.Вставить(Эл, ЗнНач); КонецЕсли; Стр[Эл]=ЗнКон; КонецЦикла; Стр[НазваниеКолонкиРезультата]=Р; //Структура изменений КонецЕсли; КонецЦикла; Возврат ТЗРез; КонецФункции |
|||
|
21
Гений 1С
гуру
10.01.07
✎
16:29
|
Окей, тема ушла в КЗ, код смотрите там: Книга знаний: v8: Сравнение двух таблиц значений с ключемыми полями
|
|||
|
22
vde69
10.01.07
✎
16:45
|
собственно вот решение проще!!! и БЫСТРЕЕ!!! Книга знаний: v8: Алгоритм синхронизации двух таблиц (по текстовому полю)
|
|||
|
23
kiruha
10.01.07
✎
16:54
|
(20) А про проблему больших ТЗ в 8.0 не слышал?
И время на больших данных измерял? |
|||
|
24
simol
10.01.07
✎
17:04
|
А если это использовать перед записью движений регистра, то вроде как если при отсутсвии изменений можно не записывать:
1. Поидее выиграш в скорости 2. Не изменяются последовательности. Как такая идея? |
|||
|
25
Гений 1С
гуру
10.01.07
✎
19:16
|
(23) У меня данные не большие, но в основном здесь работает метод свернуть, а как его ускорить, мы знаем. Книга знаний: v8: Ускорение типовой свертки таблиц значений в 1С80
(22) да, я такой метод знаю и его рассматривал, но по-моему СВЕРТКА быстрее, чем СОРТИРОВКА, да еще и построение индекса, нафиг... ;-) |
|||
|
26
Гений 1С
гуру
10.01.07
✎
19:16
|
(22) вставил кросс линки между моей и этой статьей.
|
|||
|
27
Гений 1С
гуру
10.01.07
✎
19:16
|
у меня готовая функция универсальная, а в (22) еще дописывать надо.
|
| Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |