Имя: Пароль:
1C
 
Вопрос знатокам жёстких операций под 8.2
0 Aleks73
 
19.11.10
13:06
На копии 8.2, (подключенной через сервер)
удаляю все документы с созданием битых ссылок, командой получить объект - удалить.
Написал маленькую обработочку, процесс идёт, но документов очень много.
нет ли какой-то возможности в 8.2 удалить все документы не выполняя над каждым операцию по-одиночке, а очистить место хранения документов, как для независимого регистра сведений ?
1 DrShad
 
19.11.10
13:09
[поставим закладочку]
проследим может что дельное всплавет
2 Leksus
 
19.11.10
13:14
(0) получить структуру таблиц для этого документа и очистить их через QA?
3 H A D G E H O G s
 
19.11.10
13:15
(0)
1) В SQL очистить таблицы документа. Если нельзя - тогда

а) Ставить флаг "ОбменДанными"
б) Отключить Итоги у связанных регистров перед удалением, потом включить.

Всё.
4 ilkoder
 
19.11.10
13:16
загрузка  в транзакции намного быстрее идет - может и тут поможет?
5 DailyLookingOn Sunset
 
19.11.10
13:18
Баян.
Обработка УниверсальныйОбменДаннымиXML
6 DrShad
 
19.11.10
13:18
(2) тогда останутся записив регистрах, хотя и по (0) тоже должны остаться (но возможно что на уровне платформы это отслеживается, т.е. записи в регистрах не остаются)
7 МихаилМ
 
19.11.10
13:19
8 Aleks73
 
19.11.10
13:19
(1,2) я конечно, догадываюсь, что сисадмин может как-то попробовать это сделать.
Разумеется,я имел в виду - в конфигураторе или в предприятии
9 H A D G E H O G s
 
19.11.10
13:20
(6) Отслеживается.
Для измерений РС, с флагом "Ведущий"
10 H A D G E H O G s
 
19.11.10
13:21
Можно еще попробовать
УдалитьОбъекты(МассивСсылок, Ложь);

Скорее всего тогда объекты не будут читаться при ПолучитьОбъект()
11 Aleks73
 
19.11.10
13:22
(7) мне нужно удалить полностью, а не пометить.ЖЕСТКО, с битыми ссылками
12 Aleks73
 
19.11.10
13:29
(10) интересная мысль. а по скорости ?
это писать или можно вызврать из предприятия ?
начальство бегает кругами = быстрей, быстрей, а удаляется со скоростью 100 доков в минуту !
13 ilkoder
 
19.11.10
13:32
Начальство кругами бегает? улики уничтожаете?
14 disk-2008
 
19.11.10
13:32
(8)"...удалить все документы"
Действительно все вообще удалить хочешь?
Ну, тогда базу чистую создай уж лучше.
15 disk-2008
 
19.11.10
13:33
(14) - это к (0).
16 Невский Александр
 
19.11.10
13:34
(0) сейчас занимаюсь тем же, только на 8.1

Как делаю: частично делаю через SQL-запросы напрямую, частично - в транзакции с задержкой (например, по 50 докам отменил проведение в транзакции -> попытка записи транзакции -> задержка в 1 секунду)
17 МихаилМ
 
19.11.10
13:38
(16)
зачем же нужна задержка ?
18 Aleks73
 
19.11.10
13:38
(14) нужно удалить только определённые доки
19 DrShad
 
19.11.10
13:38
(12) хз, но имхо этот метод должен быть быстрее
и про итоги не забываем
20 Aleks73
 
19.11.10
13:40
(19) а при чём тут итоги если выполняется обработка написанная на встроенном языке ?!
21 Aleks73
 
19.11.10
13:49
(16) не понял - как обычный тупой одинэсник, не имеющий доступа к средствам сисадмина, может это сделать ?
22 DrShad
 
19.11.10
13:50
(20) чтоб при каждом удалении не пресчитывались
23 Невский Александр
 
19.11.10
13:59
(17) база SQL, круглосуточно пользователей от 20 человек - нужна задержка, иначе ошибки с блокировкой выскакивают. Приходится подбирать количество доков в одной транзакции и задержку
24 Невский Александр
 
19.11.10
14:01
(21) спроси у админа пароль к пользователю админа базы SQL и соединись с ней, а лучше - пусть он тебе копию сделает, ты на ней сначала потренируешься
25 Aleks73
 
19.11.10
14:01
(22,23) я не располагаю средствами сисадмина.
Делаю на КОПИИ.
26 Aleks73
 
19.11.10
14:14
первый ап
27 Невский Александр
 
19.11.10
14:17
(25) что значит "не распологаю средствами админа"?
База SQL? Учетка и пароль известны?
28 DrShad
 
19.11.10
14:17
(25) итоги без админа отключаются
29 Невский Александр
 
19.11.10
14:20
+ Если захочешь отключить итоги - пользователи какие-нить в это время работать в базе, кроме тебя?
30 Aleks73
 
19.11.10
14:26
(27) база скл.
в смысле - учётка и пароль ? Чья ? На что ?
(29) работаю в КОПИИ. Как и дл ячего отключить итоги в 8.2 ?
31 Невский Александр
 
19.11.10
14:35
(30) даю ответ - ты можешь выбрать для оптимизации 2 способа:
1. Стандартными средствами 1C
2. Средствами SQL (прямые запросы)

Прежде чем это делать, в данном случае - только для первого случая - можно отключить итоги для еще быстрой оптимизации

Отключение итого нужно - чтобы после удаления каждого документа итоги в базе у тебя не пересчитывались (например, по регистрам накопления). Отключать или нет - тебе выбирать самому

Как отключить -
Состояние("Отключаем итоги регистров накопления ... ");
Для Каждого Регистр Из Метаданные.РегистрыНакопления Цикл
   Состояние("Отключаем итоги регистра накопления "+Строка(Регистр.Имя));
   РегистрыНакопления[Регистр.Имя].УстановитьИспользованиеИтогов(ЛОЖЬ);    
КонецЦикла;

Включить также, только в скобочках будет ИСТИНА. Включить нужно будет после того, как все сделаешь
Что хорошего в отключении итогов: Получишь оптимизацию в удалении объектов (по времени)
Что плохого в отключении итогов: если в это время кроме тебя будут работать еще какие-нить юзеры, они не смогут получить Остатки по регистрам (то есть, получать отчетность и скорее всего - 99% - провести документы)
32 Невский Александр
 
19.11.10
14:40
(31) + плохо - если база большая, время уйдет на отключение и включение итогов

Как можно удалить документы средствами 1С (можешь сделать по аналогии, у меня для отмены проведения так сделано):

ДатаОкончания = КонецДня(ДатаНачала);

Если ТранзакцияАктивна() Тогда
   ОтменитьТранзакцию();
КонецЕсли;
НачатьТранзакцию();
       Пока ДатаОкончания <= НачалоДня(ДатаСвертки) - 1 Цикл
           ЗапросПоДокам = Новый Запрос;
           ЗапросПоДокам.Текст =
           "ВЫБРАТЬ
           |    СписокДокументов.Ссылка КАК Документ
           |ИЗ
           |    Документ."+Док.Значение+
           " КАК СписокДокументов
           |ГДЕ
           |    (СписокДокументов.Проведен)        
           |    И СписокДокументов.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания";
           ЗапросПоДокам.УстановитьПараметр("ДатаНачала",ДатаНачала);
           ЗапросПоДокам.УстановитьПараметр("ДатаОкончания",ДатаОкончания);            
           РезПоДокам = ЗапросПоДокам.Выполнить();
           
           Состояние("Выполняется отмена проведения документов "+Строка(Док.Значение)+" за "+Формат(ДатаОкончания,"ДФ=dd.MM.yyyy"));

       
           ВыборкаДоков = РезПоДокам.Выбрать();
           Пока ВыборкаДоков.Следующий() Цикл
                ОбработкаПрерыванияПользователя();
                Состояние("Отменяется проведение документа  "+Строка(КолВо));
                ТекОбъект = ВыборкаДоков.Документ.ПолучитьОбъект();
                Колво = Колво + 1;
                ТекОбъект.Записать(РежимЗаписиДокумента.ОтменаПроведения);
                   
Если Колво % 50 = 0 Тогда
                   Попытка
                       ЗафиксироватьТранзакцию();
                   Исключение
                        Сообщить("Неуспешное выполнение транзакции пометки на удаление документов "+Строка(Док.Значение)+" за  "+Формат(ДатаНачала,"ДФ=dd.MM.yyyy"));
                        ОтменитьТранзакцию();
                   КонецПопытки;
                   
                   ДатаВремяПослеТранзакции = ТекущаяДата();
                   Пока НЕ ТекущаяДата() = ДатаВремяПослеТранзакции + 1 Цикл // даем на запись  пользователю 5 секунд
                   КонецЦикла;
                   НачатьТранзакцию();
               КонецЕсли;
           КонецЦикла;
           
            Сообщить("Выполнено "+Строка(Док.Значение)+" за "+Формат(ДатаОкончания,"ДФ=dd.MM.yyyy")+" "+ТекущаяДата());            
           
            ДатаНачала = ДатаНачала + 86400;
            ДатаОкончания = ДатаОкончания + 86400;
        КонецЦикла;

- у меня делается в транзакции по дням
33 Невский Александр
 
19.11.10
14:43
(32) + вторым способом - SQL, прямые запросы

Подключаемся к базе SQL -

       Connection = Новый COMОбъект("ADODB.Connection");
       String = "driver={SQL Server};server=SQLSrv;uid=sa;pwd=****;Database=OBD";
       String = "Provider=SQLOLEDB.1;Password=****;Persist Security Info=True;User ID=sa;Initial Catalog=OBD;Data Source=SQLSrv";
       Connection.ConnectionTimeOut=20;
       Connection.CommandTimeOut=600;
       Connection.CursorLocation=3;
       
       Сообщить("Установить соединение с базой данных.");
       Попытка
           Connection.Open(String);
       Исключение
           Сообщить("Ошибка во время установки соединения с базой данных!");
           Сообщить(ОписаниеОшибки());
           Возврат;
       КонецПопытки;
ГДЕ **** - прописываешь свой пароль к базе SQL

       ДатаНакладных = НачалоДня(ДатаНачала);
       
   Пока ДатаНакладных <= КонецДня(ДатаОкончания) Цикл    
       Сообщить("Начинаем отменять проведение накладных за "+Формат(НачалоДня(ДатаНакладных),"ДЛФ=DT")+" "+Строка(ТекущаяДата()));
       Состояние("Выполняется запрос SQL - помечаются документы на удаление "+Строка(Формат(ДатаНакладных,"ДФ=dd.MM.yyyy")));

       Попытка
           RS = Новый COMОбъект("ADODB.Recordset");                
           Command = Новый COMОбъект ("ADODB.Command");
           Command.ActiveConnection = Connection;
           SQL_ТекстЗапроса =
           "SET IMPLICIT_TRANSACTIONS  OFF
           |BEGIN TRY
           |    BEGIN TRANSACTION;
           |        UPDATE _Document109 SET _Document109._Marked = 1 WHERE _Document109._Date_Time >="+"'"+Формат(НачалоДня(ДатаНакладных),"ДЛФ=DT")+"' and _Document109._Date_Time<='"+Формат(КонецДня(ДатаНакладных),"ДЛФ=DT")+"'"+ " and
           |        _Document109._Marked = 0
           |    COMMIT TRANSACTION
           |    END TRY
           |    BEGIN CATCH
           |   ROLLBACK TRANSACTION  
           |END CATCH;";
           Command.CommandText = SQL_ТекстЗапроса;
           Command.CommandType = 1;        
           RS = Command.execute();
       Исключение
           Сообщить(ОписаниеОшибки());
       КонецПопытки;
           
/// Остальные запросы (пропущены)
           ДатаНакладных = ДатаНакладных +  86400;
       КонецЦикла;
       
       Сообщить("Выполнение закончилось "+Строка(ТекущаяДата()));
       Connection.Close();
34 Невский Александр
 
19.11.10
14:46
(33) + что плохого в SQL - нужно знать что и как писать, если забудешь что-то, то получишь результат "приплыли"

+ что хорошего - работает намного быстрее чем стандартным методом (испытано - 800 000 накладных - движения + пометка удаления + отмена проведения SQL делает за 1 час, стандартными методами только отмена проведения - 4-5 суток уходит)
Только после SQL нужно не забыть сделать пересчет итогов, если не выполняешь это запросом
35 Aleks73
 
19.11.10
14:47
(31) сколько это будет выполняться на скл базе ?
36 Aleks73
 
19.11.10
14:49
(34) во-во, пока не изучу что ты понаписал - не буду.
а что касается удаления в (32) то у меня написано гораздо проще потому как выполняется на копии. разумеется по такому же принципу.
так что меня сейчас интересует (35)
37 Невский Александр
 
19.11.10
14:49
(35) смотри (34)
Только если будешь использовать запросы SQL - 1000 раз примерь, 1 раз отрежь ... Я бы не стал сам их использовать - просто начальство сказало за ограниченное время базу свернуть - готовлюсь :))
38 Aleks73
 
19.11.10
14:57
(37) в (33-34) ты не написал о (31) :
Для Каждого Регистр Из Метаданные.РегистрыНакопления Цикл
   Состояние("Отключаем итоги регистра накопления "+Строка(Регистр.Имя));
   РегистрыНакопления[Регистр.Имя].УстановитьИспользованиеИтогов(ЛОЖЬ);    
КонецЦикла;
39 Невский Александр
 
19.11.10
15:04
(38) На SQL отключение - включение итогов никак не повлияет, самое главное сделать потом пересчет итогов не забыть
А при использовании стандартных способов мне нельзя отключать итоги, пользователи в это время в базе работать будут - поэтому я использую обрабатываю по дням - потом частями и впридачу задержка в секунду стоит
40 H A D G E H O G s
 
19.11.10
15:08
(31) Плохо, очень плохо
41 Aleks73
 
19.11.10
15:09
(39) а как сделать пересчет итогов ?
42 H A D G E H O G s
 
19.11.10
15:09
(40) Отключать итоги надо для тех регистров, у которых Регистратор - удаляемый документ
43 H A D G E H O G s
 
19.11.10
15:10
(41) Почитать ЖКК например, ага?
44 Невский Александр
 
19.11.10
15:12
(40) что плохого - в моем случае, когда я тренировался - все регистры нужно было отключить и включить. Поэтому так и написано
А вообще, да согласен с (42) на все 100%
45 Aleks73
 
19.11.10
15:16
(43) все пять книг , ага ?
46 Aleks73
 
19.11.10
15:17
(44),ты не ответил на (41)
47 H A D G E H O G s
 
19.11.10
15:19
(45) Нет, достаточно почитать про РН.менеджер
48 Невский Александр
 
19.11.10
15:24
(41) В Конфигураторе -> Администрирование -> ТиИ -> Пересчет итогов
(47) да знаю я это ... Просто здесь так написал :))
49 nexel
 
19.11.10
15:57
Если удалить документ одного вида... то я бы тупо скопировал DDL таблички, дропнул бы ее и создал девственно чистую... из ранее скопированного DDL ... но это так, если особо не задумываться о последствиях.

Главное потом при ТИИ не включить флаг создания убитых объектов ))))
50 Aleks73
 
19.11.10
16:05
(49) не знаю ни про какое DDL
51 Aleks73
 
19.11.10
16:12
(48) Спасибо. Сейчас пробовать такое не буду, надо изучить
52 Невский Александр
 
19.11.10
16:21
Для сравнения - при отмене проведения 1000 документов (записи в 2 РН) с отключенными итогами - 38 секунд, с включенными - 1 мин. 40 секунд
53 Невский Александр
 
19.11.10
16:22
(52) + это стандартными средствами 1С, так как написано в (32)
А если документ делает движения больше чем в 2 РН, разница будет заметна еще больше
54 Aleks73
 
19.11.10
16:29
(53) может быть .
сильно смущает пересчёт итогов в конфигураторе. я по семёрке помню как это затягивается.
55 Невский Александр
 
19.11.10
16:34
(54) у меня примерно 5-6 млн документов в базе
Правда регистров всего 5 штук - заняло 2 часа, но записей в них далеко немало
Вообще, я думаю, если документов нужно пометить немало > 500 тысяч, и по ним много движений в регистрах, и условия позволяют, то лучше с отключенными итогами, по времени выиграешь очень много
56 Aleks73
 
19.11.10
16:37
(55) документов около 50 тысяч
57 Aleks73
 
19.11.10
16:39
(55) ситуация такая. регистров ОЧЕНЬ много, насколько они заполнены, я не знаю. отключить нужно 3-4 регистра. но пересчёт итогов нужно будет делать по всем, насколько я понял. такие дела.
58 Невский Александр
 
19.11.10
16:39
(56) мало
Мне нужно будет пометить ~ 3 млн.
59 Невский Александр
 
19.11.10
16:40
(57) пройдись по ним запросами SQL, почисти и пересчитай итоги - зачем тебе тогда документы удалять?
60 Невский Александр
 
19.11.10
16:44
пример удаления записей из регистра накопления:

       Состояние ("Выполняется запрос SQL - производится очистка регистра накопления _ТоварыВСмене ... "+Строка(Формат(ДатаНакладных,"ДФ=dd.MM.yyyy")));
       Попытка
           RS = Новый COMОбъект("ADODB.Recordset");        
           Command = Новый COMОбъект ("ADODB.Command");
           Command.ActiveConnection = Connection;
           
           SQL_ТекстЗапроса = "SET IMPLICIT_TRANSACTIONS  OFF
           |BEGIN TRY
           |    BEGIN TRANSACTION;
           | DELETE FROM _AccumReg2920 WHERE _AccumReg2920._Period >="+"'"+Формат(ДатаНакладных,"ДЛФ=DT")+"' and _AccumReg2920._Period<='"+Формат(ДатаНакладных,"ДЛФ=DT")+"'"+" and
           | _AccumReg2920._RecorderTRef=0x0000006D
           |    COMMIT TRANSACTION
           |    END TRY
           |    BEGIN CATCH
           |   ROLLBACK TRANSACTION  
           |END CATCH;";
           
           //SQL_ТекстЗапроса = "DELETE FROM _AccumReg2920 WHERE _AccumReg2920._Period >="+"'"+Формат(ДатаНакладных,"ДЛФ=DT")+"' and _AccumReg2920._Period<='"+Формат(ДатаНакладных,"ДЛФ=DT")+"'"+" and "+
           //" _AccumReg2920._RecorderTRef=0x0000006D";
           Command.CommandText = SQL_ТекстЗапроса;
           Command.CommandType = 1;        
           RS = Command.execute();
       Исключение
           Сообщить(ОписаниеОшибки());
       КонецПопытки;

Здесь: _AccumReg2920 - это основная таблица РН, 0x0000006D - таблица регистратора в 16-ричной системе (в моем случае 209)

+ Обмен у тебя в базе настроен? Если да, то нужно будет рассматривать тогда ситуацию с регистрацией изменений
61 Aleks73
 
19.11.10
17:22
(60) извини, занимался другим делом. обмен у меня настроен но я сейчас правлю КОПИЮ
62 Aleks73
 
19.11.10
17:23
С SQL я буду пробовать КРАЙНЕ осторожно на чисто моей базе
63 Aleks73
 
19.11.10
17:26
(57) я хочу пройти оптимально как администратор-программист базы - и без SQL.
Как ?
64 hhhh
 
19.11.10
17:40
(63) сделай, как в (3) написано

ТекОбъект.ОбменДанными.Загрузка = Истина;

тогда она будет думать, что удаление пришло по обмену из другого узла и регистры трогать не будет.
65 Aleks73
 
19.11.10
18:34
(64) ушол, в понедельник обсудим !
Чтобы обнаруживать ошибки, программист должен иметь ум, которому доставляет удовольствие находить изъяны там, где, казалось, царят красота и совершенство. Фредерик Брукс-младший