Задвоение элементов плана счетов в базе на SQL.

Иногда приходится разбираться с "грехами отцов", когда приходишь к клиенту, а до тебя наделали делов.

Вот, собственно, проблема:
Настраивали когда-то план обмена, все работало штатно. Потом обмен пошел не как надо и в справочниках появились задвоенные предопределенные элементы. В общем, на Инфостарте нашел кучу обработок, которые помогут. Но тут оказалось, что если работать с элементом "ПланСчетов", эти обработки бесполезны.

Итак, суть бесполезности обработок:

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

Да, можно и тут постараться определить, какой из задвоенных является искомым «правильным», но только на глаз. Добавить к счету синтетический код нельзя, так как тогда появится ошибка о неуникальности записываемого элемента.

Короче, полная шляпа.

В голову пришла хорошая идея, которая отработала на ура:

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

Делаем Select такого вида (у меня задвоение прошло по 96 счету):

SELECT [_IDRRef]
,[_Version]
,[_Marked]
,[_PredefinedID]
,[_ParentIDRRef]
,[_Code]
,[_Description]
,[_OrderField]
,[_Kind]
,[_OffBalance]
,[_Fld530]
,[_Fld531]
,[_Fld18988]
,[_Fld532]
,[_Fld533]
,[_Fld534]
,[_Fld535]
FROM [ИмяВашейБазыНаСервере].[dbo].[_Acc15]
Where [_Code] Like '96%'

(чтобы определить, в какой таблице лежит «ПланСчетов», нужно воспользоваться любой обработкой анализа структуры БД на SQL или попробовать разобраться тут — https://its.1c.ru/db/metod8dev#content:1591:hdoc)

Получаем табличку с данными:

[_IDRRef] [_Version] [_Marked] [_PredefinedID] [_ParentIDRRef] [_Code]

0x815400155D03291711E51846D90DC41A
0x815400155D03291711E51852F63B454F
0x815400155D03291711E51846D90DC412
0x815400155D03291711E51852F63B4547
0x815400155D03291711E51846D90DC414
0x815400155D03291711E51852F63B4549
0x815400155D03291711E51846D90DC421
0x815400155D03291711E51852F63B4556
0xAD69A720D0E7A9EB47D4D2002DF3F975
0xA9B50CDB35CD890046E60B617F27AB4E

0x00000000017933DD
0x00000000017933EF
0x00000000017933D5
0x00000000017933E7
0x00000000017933D7
0x00000000017933E9
0x00000000017933E4
0x00000000017933F6
0x000000000179350F
0x00000000017934FB

0x00
0x00
0x00
0x00
0x00
0x00
0x00
0x00
0x00
0x00

0xBEA8FB94C602B84545099B8D8AE52424
0xBEA8FB94C602B84545099B8D8AE52424
0x97A0CB0321E956714386231A1CEECB79
0x97A0CB0321E956714386231A1CEECB79
0x98CB88ECEB17AC374447CDBD3EEB439B
0x98CB88ECEB17AC374447CDBD3EEB439B
0xBF089DA9D107FF9B46A4DDF7EEE4F82E
0xBF089DA9D107FF9B46A4DDF7EEE4F82E
0xAD69A720D0E7A9EB47D4D2002DF3F975
0xA9B50CDB35CD890046E60B617F27AB4E

0x00000000000000000000000000000000
0x00000000000000000000000000000000
0x815400155D03291711E51846D90DC41A
0x815400155D03291711E51852F63B454F
0x815400155D03291711E51846D90DC412
0x815400155D03291711E51852F63B4547
0x815400155D03291711E51846D90DC412
0x815400155D03291711E51852F63B4547
0x815400155D03291711E51852F63B454F
0x815400155D03291711E51852F63B454F

96
96
96.01
96.01
96.01.1
96.01.1
96.01.2
96.01.2
96.09
96.33

 

В этой таблице мы видим данные, которые уже взяты не с потолка и поддаются анализу.

Обратите внимание, задвоился не весь 96 счет, а лишь его часть. Таким образом можно установить, что [_IDRRef] «Правильного счета» — 0x815400155D03291711E51852F63B454F, так как он описан как родитель в незадвоенных элементах в колонке [_ParentIDRRef].

В общем, после анализа делаем проверочный запрос, чтобы убедиться, что будем удалять то, что надо:

SELECT [_IDRRef]
,[_Version]
,[_Marked]
,[_PredefinedID]
,[_ParentIDRRef]
,[_Code]
,[_Description]
,[_OrderField]
,[_Kind]
,[_OffBalance]
,[_Fld530]
,[_Fld531]
,[_Fld18988]
,[_Fld532]
,[_Fld533]
,[_Fld534]
,[_Fld535]
FROM [ИмяВашейБазыНаСервере].[dbo].[_Acc15]
--Where [_Code] Like '96%'
Where [_IDRRef] IN
(0x815400155D03291711E51846D90DC41A
,0x815400155D03291711E51846D90DC412
,0x815400155D03291711E51846D90DC414
,0x815400155D03291711E51846D90DC421)

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

Теперь можно выполнить Delete:

USE [ИмяВашейБазыНаСервере]
go

DELETE FROM [dbo].[_Acc15]
WHERE [_IDRRef] IN
(0x815400155D03291711E51846D90DC41A
,0x815400155D03291711E51846D90DC412
,0x815400155D03291711E51846D90DC414
,0x815400155D03291711E51846D90DC421)
go

В итоге — задвоение убрали, БД целая. Едиственное, о чем стоит упомянуть — если по удаляемому счету есть обороты, сначала их надо перекинуть на «правильный счет» обработкой «Подбор и замена значений».

Нужно также понимать последствия ошибочно выбранного счета, поэтому сделайте перед манипуляциями бэкап БД, и можно экспериментировать.


ВНИМЕНИЕ!!! Данное действие может нарушить лицензионное соглашение с компанией 1С. Будьте внимательны!

16 Comments

  1. AlX0id

    Есть более интересная проблема:

    1. Задвоились виды субконто. Как, где, почему — фигзнает.

    2. Один из видов субконто — был предопределенным. Стал — нет. (Как?? хз). Бред, конечно, но в конфигураторе в плане счетов указан на 94 счете «Неизвестный элемент» — видимо, это он. Все ссылки в данных — на него.

    3. Второй — ныне предопределенный, но ссылок на него вообще нет.

    Так вот вопрос — как же сделать так, чтобы элемент из п.2 стал предопределенным? И с нужным наименованием в конфигураторе?

    Reply
  2. qwed557

    Это нарушение лицензионного соглашения 1С. Там прописано, что запрещено любое вмешательство в структуру базы данных, кроме как из языка.

    Reply
  3. Danila-Master

    http://v8.1c.ru/predpriyatie/questions_licence.htm

    Пунк 65:



    Нельзя обращаться к данным информационной базы напрямую, минуя уровень объектов работы с данными «1С:Предприятия» — например при помощи средств СУБД или при помощи внешних компонент, которые реализуют прямой доступ к СУБД. Это ограничение распространяется на любые действия с данными, в том числе на изменение их структуры, а так же на чтение или изменение самих данных информационной базы или служебных данных «1С:Предприятия».

    Reply
  4. AlX0id

    (3) Danila-Master,

    «Данное ограничение необходимо для обеспечения стабильности работы механизмов системы, осуществления поддержки и возможности перехода на новые версии «1С:Предприятия».»

    А если она и так уже не стабильно работает (задвоены предопределенные элементы) — то что вы предлагаете делать? Ждать от ТП 1С ответа?

    Reply
  5. oleg212

    УстановкаПредопределенныхЭлементов Вам в помощь и прямые руки. Успеха!

    Reply
  6. vasyalisk88

    (1) AlX0id, В конфигураторе их 2 или 1? Напиши простенькую обработку, которая сделает привязку, как вариант, иначе пользуйся обработкой переноса привязок, их на форуме полно.

    (3) Danila-Master, О каком лицензионном соглашении может идти речь, если БД с задвоенным ТИПОВЫМ планом счетов не пригодна для эксплуатации. Это косяк тех, кто эту платформу пишет. Если бы они реально сделали механизм, который контролировал предопределенные элементы на уникльность и не давал бы всяким «программистам» делать недопустимые вещи, тогда да, согласен. А в данный момент, если у тебя задвоится полностью план счетов хозрасчетный, придется с бэкапа восстанавливать базу. Они же не подключатся и не исправят косяк.

    А вот с точки зрения разработки — у тебя не было такой проблемы, когда в конфигураторе не описан элемент, а в на SQL он есть?

    Вот пример:

    1й раз открываю конфигуратор клиента, причина обращения — база не открывается вообще. Выдает ошибку, не найдена таблица базы данных. Оказалось, на SQL действительно есть объект класса справочник, а в конфигураторе его нет. И вот как быть? Звонить в 1С? Что они тебе ответят? Восстановитесь с бэкапа? Который был день назад? Это неприемлемо, когда можно починить и ты знаешь как. Продукт работает, справочник удален, конфа восстановлена в типовую.

    Вот серьезно, ЛС это круто, но толку от него — отмазка не делать!

    Написано черным по белому — Данное ограничение необходимо для обеспечения стабильности работы механизмов системы, осуществления поддержки и возможности перехода на новые версии «1С:Предприятия».

    Но оно не выполняется самой 1С. Не раз звонил в техподдержку 1С, восстанавливайтесь с Бэкапа говорят. А если бэкап был 5 лет назад? Мне новую базу с вводом остатков делать?

    Давайте подробно, что означает задвоение типовых элементов в базе, а не в конфигураторе? Ошибка чего? Встроенного языка? «Фишка» платформы? На 8.2 даже о такой не думал. А тут реально шляпа.

    (4) AlX0id, дождался, восстановитесь из бэкапа. Не стал бы туда лезть, черт там ногу сломит.

    Ребят, серьезно, пусть программа соответствует заявленным характеристикам. Тогда ни в жизни никто не полезет в SQL составляющую. Или давайте 1С будет в рамках своих косяков БЕСПЛАТНО лечить такие косяки всем, а не предлагать восстановление.

    Если есть предложения, как сделать иначе, очень хотел бы попробовать иной способ.

    Reply
  7. vasyalisk88

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

    (5) oleg212, она то как раз и не помогла…

    Reply
  8. ekaruk

    (7) А что значит «Не помогла»?

    Она как раз может сделать предопределенными элементы с данными вместо левых.

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

    Reply
  9. vasyalisk88

    Кстати, по поводу ЛС, очень внимательно почитал. И возник такой вопрос — есть внешняя компонента, в которую необходимо выгружать данные из 1С, напрямую. И компания не хочет нанимать для этого специалиста по 1С предприятию, а хочет сделать это через загрузку данных напрямую из SQL таблиц 1С, так как например эта вещь написана самой компанией. Выходит, что компания-разработчик обмена будет нарушать ЛС с 1С, описывая подобный прямой обмен?

    P.S. Вопрос риторический. Да будет. И сделает. И 1С не узнает, так как структура БД не нарушена, все работает и даже обновляется типовым обновлением.

    Буду искать альтернативное решение, если найду, отпишу.

    Reply
  10. vasyalisk88

    (8) ekaruk, Итак, подробнее, обе базы подключены к 1 хранилищу, соответственно конфигурации идентичны. Тот, кто писал обмен, либо не знал, о том, что можно проверить элемент на предопределенность, либо просто пренебрег этим. Собственно в конфигурации 1 предопределенный элемент. В самой базе их 2. При попытке этой обработкой что-либо сделать с этими задвоенными счетами, выходят ошибки, как в этой публикации — http://infostart.ru/public/310542/ . Собственно когда меняю привязку элемента, выходит ошибка вида — Этот объект имеет ссылки на предопределенный элемент субконто.

    Я думал, что можно зайти в конфигуратор, удалить с этого счета субконто… но! элемент в конфигураторе 1! То есть я поломаю к чертям все настройки этого счета. И не факт, что после этого что-то будет нормально работать.

    И кстати, как мне достоверно определить, какой из счетов верный, если они оба 96?)

    В обработке выбор идет как в БД, то есть это рандом. Я могу случайно перекинуть на «левый» счет. А ссылка хоть и ПК, но не видна в списке выбора элементов. Код — 96 у обоих одинаковый)

    Reply
  11. AlX0id

    (6)

    В конфигураторе их 2 или 1? Напиши простенькую обработку, которая сделает привязку, как вариант, иначе пользуйся обработкой переноса привязок, их на форуме полно.

    В конфигураторе 1 вид. Обработки переноса привязок работают, начиная с режима совместимости 8.3.3, а у клиента УПП (режим 8.2.13).

    То есть, предопределенный удалить в скуле для меня не большая проблема.. Вопрос, как система поймет, что вот тот не предопределенный должен стать предопределенным?

    Reply
  12. vasyalisk88

    (11) AlX0id, смотри (5) oleg212, — ты этой обработкой установишь нужное значение элемента, обработка устанавливает привязку предопределенного элемента к указанному, снимая тем самым предопределенность с другого. Я правильно понял, что у тебя нет предопределенного элемента впринципе?

    P.S. Так сори, плохо понял что ты написал — смотри, у объекта есть признак — «ИмяПредопределенныхДанных». В нем как раз и указывается имя предопределенного элемента, к которому должна быть привязка. К несчастью нет под рукой базы на платформе 8.2… В 8.2 такого нет, там все иначе жеж!!! Там такого не было, у тебя точно есть элемент в конфигураторе, которому нет соответствия? Можно скрин из конфигуратора и приложения?

    Reply
  13. ekaruk

    (10) В той базе, где элементы в единственном экземпляре, переименуйте их временно. Например, добавить точку в название счета. Потом синхронизируйте базы. И во второй отвяжите те, которые без точек и с них перенесите данные на правильные.

    Reply
  14. vasyalisk88

    (13) ekaruk, Могу видео запилить даже, я же писал — они не отвязываются из-за того, что на 96 счете есть предопределенное субконто. Как его убрать можно, не заходя в конфигуратор и не убивая это субконто в плане счетов?

    Reply
  15. AlX0id

    (12)

    В итоге решили не лезть в SQL — поправили в конфигураторе вид субконто у плана счетов и перенесли на него все движения..

    Так что показать не могу )

    Reply
  16. vasyalisk88

    (15) AlX0id,

    Вариант, хорошая идея!

    Погуглил — оказалось, что тестирование и исправление ДОЛЖНО было исправлять эти косяки, поробовал, не исправляет (храню базу с задвоенным планом счетов как память, вдруг когда-нибудь само вылечится тестированием).

    Вообще нашел другое решение, надо написать простенькую обработку, которая по Uid отберет все нужные значение, но все равно надо лезть в SQL и смотреть, какой же из элементов задвоен. Но в этом случае мы ничего не меняем, что по мнению 1С правильно. Так же можно взять Uid владельца и установить связь. Правда не тестировал, но в теории, если еще Интерактивно вынести эти элементы, то ок вроде. Нужно ли будет снимать предопределенность при интерактивном удалении? Беда опять в том, что если нет, Мы лезем в предопределенный счет, меняем субконто и т.д.

    Это просто замкнутый круг… (с)

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *