Запись не верна набор записей принадлежащий менеджеру записи должен содержать ровно 1 запись 1с

Обновлено: 06.07.2024

Как в модуле набора записей отличить изменение записи от ее удаления? При изменении записи сначала формируется событие на удаление этой записи (Замещение=истина), потом событие на добавление этой записи (Замещение=ложь). При удалении записи просто формируется событие на удаление записи (Замещение=истина). Никак отличить не могу, поможите дальтонику.

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

Т.к. при модификации сначала вызывается удаление, если его запретить - модификация не пройдет.

Попробуй закончить транзакцию принудительно раньше конца процедуры и посмотреть, что твориться в регистре. ЗЫ. Вроде 1С не поддерживает вложенных транзакций?

Выгрузка в таблицы значений с последующим сравнением не поможет?

Это извращение! Первым идет удаление, а не запись, поэтому что выгружать? Таблица то пустая!

Походу очередная дыра функционала. Можно еще както играться с флажком замещение, но мне кажется ДЫРА.

расскажи, чо хочеш в результате получить - может, кто другой метод предложенить, помимо "игры на замещении".

так я уже рассказал - хочу разрешить редактирование (но только ресурсов, без измерений), но запретить удаление.

Судя из того что есть только право "Изменение" у регистра, ты такое не словишь

гыгыгы. при чем тут права. Речь идет о контроле из модуля.

Не думаю, что дыра - скорее задача не с той стороны решается. С точки зрения системы происходит не модификация, а удаление и создание - а это две большие разницы и отловить можно только внешней оберткой, т.к. система не будет себя нагружать такими подробностями интимной жизни пользователя :)

чем запись отличается от удаления? в том и в другом случае записывается набор

Это мне напоминает ситуацию - захватили немцы деревню, староста бежит и грит - а че, немцы они хорошие, ничего, жить можно. В том то и дело, что невозможность отличить модификацию от удаления ведет к тому, что контроль над изменениями в регистрах сведений нужно как в 77 выносить в форму. А насчет того, что это одно и то же - бросьте. В одном случае это удаление, в другом транзакция из удаления и добавления.

Не прав. Это просто запись в обоих случаях. Просто удаление и модификация - это частный случай записи. База переходит из одного состояния в другое - это основной принцип транзакций, поэтому никак не отследит не перехватывая такие события заранее.

В оперативной памяти компьютера (Какой вопрос, такой ответ). ОФФ: Витя, ты ее сколько лет хранить собираешься? :) /2 И тебе не под силу добавить перед удалением выгрузку в ТЗ?

Да ну? Видишь ли, в теории реляционных СУБД есть оператор SQL UPDATE. 1С почему то использует не UPDATE, а DELETE & INSERT

Читаем про UPDATE и для чего оно применяется: "Важно. Инструкция UPDATE не создает набора результатов. Обновление записей, выполненное с использованием запроса на обновление, нельзя отменить. Чтобы узнать какие записи будут обновлены, выполните запрос на выборку с теми же условиями, и только потом, выполните запрос на обновление. Рекомендуется всегда делать резервные копии данных. Если записи были удалены по ошибке, их можно восстановить из резервных копий. " Т.е. это опять частный случай записи (грубо говоря - с применение отбора, что будем менять)

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

мне нужно запретить на программном уровне изменение скажем, реквизита регистра сведений определенным пользователям. Через форму - это вчерашний день, 77, да, там это было нормально.

мдя, как все запущено. видишь ли, если бы 1С передавало в модуль передзаписью, что именно оно пытается сделать. Кстати, а может для РС пощупать при записи. Я вот тут подумал.

Я так полагаю, что система не задумывается о таких мелочах просто делает удаление+запись нового - так быстрее будет.

Об этом должна была не система думать, а проектировщики платформы. Нужен был еще один параметр в процедуре ПередЗаписью (Удаление из модификации / Чистое удаление), на скорости это никак бы не отразилось. Очередная черная функциональная дыра 1С.

Ты не понял - это работает также, как и UPDATE в SQL. Т.е ВСЕ изменения ты должен перехватывать на стадии ДО, а не ВО ВРЕМЯ. Т.е надо убирать не следствие, а причину. Данная функция не предназначена для такой ситуации по причине того, что система не задается вопросом (имхо) изменение каких полей произошло, а просто обновляет запись полностью, что должно быстрее быть, т.к. UPDATE будет работать с отбором. Соответственно - такого флага (модификация или что-нибудь другое) быть не может.

Это было бы справедливо, если бы 1С изменяло через UPDATE, но оно изменяет через DELETE +INSERT, причем не средствами SQL, а из языка.

Работает четко Тонкость: при записи процедура отрабатывается дважды - первый раз удаление (количество = 0), второй раз запись проводок (количество = количество проводок); при отмене проведения - один раз (количество = 0)

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

Коряво - но подключай обработчик ожидания на 1-10 сек и смотри, что там произошло за это время. Итого у тебя не так много вариантов решить эту задачу, либо ставить ее по другому :)

В уже почти все написано. Остается в модуль набора добавить переменную-счетчик: первй вызов - удаление, второй - запись новых данных.

Хотя стоп, это идея. ПередЗаписью вызывается дважды. А контроль нужно вносить в ПриЗаписи. Точно, счетчег поможет.

Правда, непонятно, если я в ПриЗаписи напишу Отказ, разорвет ли оно всю транзакцию или только первую запись? Наверное всю!

у тебя будут проблеммы с транкзациями. ведь она может иметь неопределенное кол-во записей, то есть если я в модуле проведения документа в цикле обнавляю 100 элементов регистра, то ты получишь транкзацию (не явную) на 200 шагов. и как ты сможе из большой транкзации вычленить 1 запись. ИХМО - либо будет МЕДЛЕННО либо не получиться.

Нет, ни хрена, все счетчики, которые создаются в модуле набора записей для каждой записи уникальны, т.е. дважды устанавливаются в неопределено. Мдя.

Вообщето при удалении документа вызывается ПриЗаписи где уже свойство ПометкаУдаления = Истина

Когда вызывается призаписи транзакция уже началась Соответсвенно отказ отменяет все

v8: Как отличить запись от удаления? Вот тема. нигде про набор записей

нет это ты не понял. именно это я и хотел до тебя донести, ведь почти всегда модуль регистра выболняеться в БОЛЬШОЙ и ВЫШЕСТОЯЩЕЙ транкзации, и ты не сможешь влиять на конкретную запись. ты сможешь только отменить БОЛЬШУЮ транкзацию.

а отменять ее лучше из того места где она началась например из модуля документа.

Зачем в документы ввели событие ПередЗаписью? ЧТобы не искать по коду, где вызывается запись документа. А ты предлагаешь регресс - назад к 77. Ищем все места, где вызывается запись набора записей и ура. Только это все уже в прошлом, вместе с 77.

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

Что-то у меня все сильнее крепнет мысль, что Гений не с той стороны задачу решает. Если тебе тупо надо решать вопрос запрета редактирования чего-либо в РС - дык создай свою форму обработки списка/записи и балуйся этим. А Документы.ПередЗаписью никаким образом не относятся к РС.НаборЗаписей.ПередЗаписью - вообще разная тактика работы и назначение

я придумал как тебе сделать. все ГениТальное - ПРОСТО. 1. ЗАПРЕЩАЕШЬ ВСЕМ РОЛЯМ изменять регистр 2. Создаешь модуль с неограничеными правами и в нем описываешь процедуры записи и удаления регистра. далее ЛЮБАЯ обработка обязана пойти через твои обработчики есть 2 минуса 1. придеться переписывать ВСЕ места где происходит запись 2. возможно обойти из другого привелигерованного модуля

Гений опять изобретает сферического коня. Ты когда последний раз заходил в конференцию для партнеров? Почитай посмотри скока там пожеланий/недоработок/багов в платформе. Хоша кто тебя такого красавца туда пустит.. Попроси кого там тему замутить, есть шанс что одинэсники тебе ответят (меня не проси, сижу под паролем двухлетней давности, не хочу светиться)

+ Имелась в виду конференция для разработчиков, ессно

ой, моська ;) исчо кто кого опустит, хотелось бы мне посмотреть ;)

1. Создать глобальную переменную глПризнакЗаписи. 2. Подписать документы на событие ПередЗаписью, и ПриЗаписи 3. В обработчике событий в процедуре ПередЗаписью: глПризнакЗаписи = 0. 4. В обработчике событий в процедуре ПриЗаписи: глПризнакЗаписи = 1. 5. В обработчике событий в процедуре ПриЗаписиРегистровНакопления: условие (глКДО_ПризнакЗаписи = Истина) И (Источник.мТаблицаДвижений = Неопределено) выполнится только для удаления при изменении.

а теперь прочти свой пост ВНИМАТЕЛЬНО . и зацени - почему над тобой стебаются - просто жесть , такой самовлюбленности давно не встречал - типа новый божок.

Ненадежно. К тому же метод работает только для регистров, подчиненных регистратору. Вот то-то и оно, что большинство тупых 1сников просто плескается в своем болотце и не ждет милостей от Селезневки.

У меня все отлично отрабатывает. Думаю достаточно надежно.

я объяснил тебе, что это только для регистраторов. для независимых регистров не катит, а у меня именно такой случай. Кстати, в твоем варианте думаю достаточно анализировать реквизит Проведен документа, а не глобальные флаги.

Конечно, тебе тогда не подходит. Внутри ПриЗаписиРегистровНакопления Проведен всегда истина, как ни странно.

А ты используй версию из базы данных. Регистратор.Ссылка.ПолучитьОБъект

Проверила: Регистратор.Ссылка.ПолучитьОбъект.Проведен тоже всегда ИСТИНА в ПриЗаписиРегистровНакопления.

ты это к чему? А ваще я пока еще на 8.1 не перешел, поэтому подписку на события юзать не могу.

Проверила: Регистратор.Ссылка.ПолучитьОбъект.Модифицированность всегда ЛОЖЬ в ПриЗаписиРегистровНакопления.

это ты кому? Я проверил. Если в модуле набора записей количество записей равно нулю и модифицированность - истина, тогда это удаление, если же модифицированность - ложь, то это изменение. Действительно, отличить удаление от модификации можно. ;-) Спасибо HHHH

А у меня Модифицированность возвращает всегда ЛОЖЬ :(

ты не так смотришь. проверь еще раз. в модуле набора записей в событии перед записью!


В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "///// echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1.
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

global $wpdb2;
global $failure;
global $file_hist;

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
///// echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
>

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure) ///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
///// echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
///// echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
>
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist); ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7]; ////получаем размер файла
$m_mtime_file=$masiv_data_file[9]; ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

///// echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
///// echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
///// echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
< foreach ( $results as $r)
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
>
>
>
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
///// echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
///// echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
>

////загружаем данные
$table='vin_history'; // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация // (путь от корня web-сервера)
$delim=';'; // Разделитель полей в CSV файле
$enclosed='"'; // Кавычки для содержимого полей
$escaped='\

Читайте также: