Странный баг

Тема в разделе "1C и всё что с ней связано", создана пользователем Истребитель, 16 июн 2011.

  1. Истребитель

    Истребитель Well-Known Member

    Регистрация:
    9 июн 2010
    Сообщения:
    110
    Симпатии:
    0
    Добрый день.

    Есть код внешенй обработки, который при помощи com объекта обращается из базы данных (приёмник) 1С 8.1 в другую базу данных (источник) 1С 8.1 .
    Считывает из неё список документов (конкретных, счета на оплату покупателя) и что-то с ними делает и пишет в текущую базу.

    Источник находится на 1С 8.1 СЕРВЕРНОЙ
    Приёмник находился на 1С 8.1 ФАЙЛОВОЙ

    В коде существует место, где аттрибут документа, полученного из ком объекта, передаётся в функцию

    То есть:
    Док - это ссылка на документ, полученный через Com объект представляющий собой базу на севрере 1С 8.1

    Есть функция:
    Код ( (Unknown Language)):
    Функция Тест (Строка1)
    Если Строка1="" Тогда
    Строка1="Значение_По_Умолчанию";
    КонецЕсли;
    ...
    Возврат Найденное_Значение;
    КонецФункции
    Дальше вызывается функция от аттрибута документа:
    Код ( (Unknown Language)):
    НайденныйСклад = Тест(Док.Склад.Наименование);
    Так вот, пока база Приёмник была ФАЙЛОВАЯ, всё работало нормально!

    Перенесли базу Приёмник на СЕРВЕР. Перенос путём создания новой пустой базы и загрузки базы из файла dt. После этого то место в коде, где переданному параметру присваивается значение, стало выдавать ошибку!

    Ошибка при установке значения атрибута контекста Строка1 Метод не найден

    Посмотрел код - тип значения Строка1 - строка. Обычная такая строка. Однако ошибка. Какого хрена? И почему она появилась после переноса кода на сервер?

    Сделал так, что убирает ошибку:
    Код ( (Unknown Language)):
    Функция Тест (Строка2)
    Строка1=Строка2;
    Если Строка1="" Тогда
    Строка1="Значение_По_Умолчанию";
    КонецЕсли;
    ...
    Возврат Найденное_Значение;
    КонецФункции
    Внимание вопрос(Ы)!

    1) Правильно ли я сделал, что так убрал эту ошибку? Не утопил ли я крысу в колодце, так что она затем сгниёт и всё умрёт от чумы?
    2) Почему вообще возникает эта ошибка?
    3) Почему она возникла только после перехода на сервеную базу?
    4) Почему добавление одного присваивания исправляет ошибку?

    И финальный вопрос:

    Правильно ли я понимаю, что оператор = присваивает значение, а не ссылку, всегда, то есть:

    Код ( (Unknown Language)):
    Х="А";
    У=Х;
    Х="Б"
    У будет равно по прежнему "А"
    Но в функцию передаётся ссылка? То есть:

    Код ( (Unknown Language)):
    Функция Ф(Х)
    Х="Б";
    КонецФункции;

    Х="А"
    Ф(Х);
    Х будет равно "Б"
    Но тогда почему раньше эта ошибка не вылазила?
    И вылезла только после переноса?

    Поясните плиз...
     
  2. Дайнеко

    Дайнеко Well-Known Member
    1C Team

    Регистрация:
    19 ноя 2009
    Сообщения:
    951
    Симпатии:
    0
    Ой!
    Ф-ии дали на входе параметр типа ссылка: Тест(Док.Склад); Где Склад ну явно не строка а справочник "Склады".
    Не понимаю я вот чего:
    - Почему ее сравнивают с строкой ?
    - Дальше еще веселее: ей присваивают строку! Это все равно что написать Док.Склад="Значение_По_Умолчанию";
    - "Посмотрел код - тип значения Строка1 - строка. Обычная такая строка." Вот действительно Какого ....? Если должен быть справочник.
     
  3. Истребитель

    Истребитель Well-Known Member

    Регистрация:
    9 июн 2010
    Сообщения:
    110
    Симпатии:
    0
    Склад там это строка!
    Правда строка.
    Я проверял через "вычислить значение". Док.Склад это свойства объекта Док и оно типа строка.

    UPD: Ошибся, Док.Склад это и правда не строка, в функцию же передаётся его наименование, т.е. Док.Склад.Наименование
     
  4. Дайнеко

    Дайнеко Well-Known Member
    1C Team

    Регистрация:
    19 ноя 2009
    Сообщения:
    951
    Симпатии:
    0
    Ошибка - результат корявого программирования. Ф-ии дали параметр. Нормальная ф-ия должна взять его, что-то вычислить и вернуть свой результат, при этом не изменяя входные параметры.
    Зачем в ней надо было:
    Если Строка1="" Тогда
    Строка1="Значение_По_Умолчанию";
    КонецЕсли;
    Т.е. мимоходом "портим" входной параметр.
    В возврате-то все равно какая-то переменная "Найденное_Значение".
    Была цель изменить "Док.Склад" в "Значение_По_Умолчанию" ?

    Что касается "Я проверял через "вычислить значение"" - не верю. Если "Док" это объект в базе, открытой через COM, то навряд отладчик покажет красиво его тип, наверно показывает его представление. Лучше не гадать, а откройте конфигуратор базы-источника и покажите кусок описания структуры. А я приготовлюсь уши отрывать.
     
  5. Истребитель

    Истребитель Well-Known Member

    Регистрация:
    9 июн 2010
    Сообщения:
    110
    Симпатии:
    0
    1) Код не мой, поэтому не могу сказать какова была изначальная цель
    2) Код 100% работал 100% без вылетов на этом месте, то есть когда база, в которой обработка открывалась, была файловой, присваивание строки в этот аттрибут РАБОТАЛО КОРРЕКТНО
    3) При переходе на клиент-серверную базу, открытие и запуск обработки стал выдвать вот эту ошибку.

    Таким образом, независимо от того, какого типа какой объект в каком конфигураторе, вопрос в другом - почему на клиент серверной базе ошибка, а на файловой её нет?

    Однако прошу прощения, я вас дезинформировал.
    Передается не склад, а его наименование - Док.Склад.Наименование
    Склад действительно имеет тип справочник.склады в оригинальной базе.
     
  6. Дайнеко

    Дайнеко Well-Known Member
    1C Team

    Регистрация:
    19 ноя 2009
    Сообщения:
    951
    Симпатии:
    0
    А че голову ломать? Код некорректный - значит надо править. И что с того, что раньше работал. Разве что на душе более тоскливо.
     
  7. Hryv

    Hryv Гость

    :lool:

    с чего вы это взяли?
    в нормальных языках, типа С++, есть четкое разделение понятий значение и ссылка
    в общем случае можно умышленно использовать конструкции типа
    Код (Text):
    Функция Ф(Х)
    Х="Б";
    КонецФункции;

    Х="А"
    Ф(Х);
    Х будет равно "Б"

    другое дело, что в 1С, где практически все явное неявно, а неявное явно лично я уже рефлекторно избегаю присвоения значений в сомнительных или неоднозначных ситуациях
    и не только я
    в 1С 7.7 широко распространено, например: а=СокрЛП(б);


    честно, я не знаю как 1С 8 все это обрабатывает и даже не удивлен, что на файлах и сервере работает поразному
    Истребитель, думаю, что ваше решение вполне приемлимо
    Код ( (Unknown Language)):
    Функция Тест (Строка2)
    Строка1=Строка2;
    Если Строка1="" Тогда
    Строка1="Значение_По_Умолчанию";
    КонецЕсли;
    ...
    Возврат Найденное_Значение;
    КонецФункции
    Добавлено: Кстати говоря в том же 1С полно случаев передачи контекста в процедуру или функцию, где этот контекст потом вдоль и поперек подвергается изменениям
     
  8. Дайнеко

    Дайнеко Well-Known Member
    1C Team

    Регистрация:
    19 ноя 2009
    Сообщения:
    951
    Симпатии:
    0
    Да! Я против того, чтобы Ф-ия меняла входные параметры.
    Код ( (Unknown Language)):
     Так будет почти правильно (зачем вообще переприсваивать?):
    Функция Тест (Строка2)
    Строка1=Строка2;
    Он же приводит пример:
    Код ( (Unknown Language)):
    Функция Тест (Строка1)
    Строка1="Значение_По_Умолчанию";
    Возврат ДругаяПеременная;
    Внимательно на названия переменных посмотрите. Здесь же изменяется входной параметр. Я говорю не столько о работоспособности, сколько о стиле, который и является залогом надежности.

    А еще одним из элементов хорошего стиля является внятное название переменных. От цифирек глаза рябит.
    В общем, я бы за такой код руки оторвал.
     
  9. unknown181538

    unknown181538 НеГуру
    1C Team

    Регистрация:
    28 дек 2008
    Сообщения:
    1.418
    Симпатии:
    0
    Что-то про Синтаксис-Помощник не вспомнили:

    т.е. можно писать Функция МояФункция(Знач Параметр
    получается, что раньше неправильно работало? Честно говоря, не верю ;)
     
  10. vbs

    vbs Well-Known Member

    Регистрация:
    18 фев 2007
    Сообщения:
    1.708
    Симпатии:
    3
    В порядке флуда.
    Работал я много лет назад с одним классным программистом.
    Вот он писал примерно так (код был на Паскале, поэтому привожу русский аналог) :

    Процедура ЗакрытьВспомогательныеТаблицыИОставитьПрограммуРезидентной(СписокПереданныхПарам
    етров,СписокЗакрываемыхТаблиц)

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

    unknown181538 НеГуру
    1C Team

    Регистрация:
    28 дек 2008
    Сообщения:
    1.418
    Симпатии:
    0
    Слишком длинные тоже не очень люблю (ПроцессорВыводаДанныхСистемыКомпановкиВТабличныйДокументИмениНуралиеваБорисаГео
    ргиевича).
    Плохо читается, когда много подобных переменных.
     
  12. vbs

    vbs Well-Known Member

    Регистрация:
    18 фев 2007
    Сообщения:
    1.708
    Симпатии:
    3
    Ну, согласен, лучше покороче. Но у описываемого мастера это были в основном названия процедур.
    Понятно, что счетчики цикла и прочую лабуду он не заморачивался именовать информативно
     
  13. unknown181538

    unknown181538 НеГуру
    1C Team

    Регистрация:
    28 дек 2008
    Сообщения:
    1.418
    Симпатии:
    0
    Сегодня правил обработку с глобальными переменными:
    "перем дз, дт, динд, табт, табк;

    Процедура НачатьД()
    динд=1;
    дз=Новый XBase; "
    Хотелось совершить какое-нибудь членовредительство в отношении автора, чтобы больше не писал.
     
  14. vbs

    vbs Well-Known Member

    Регистрация:
    18 фев 2007
    Сообщения:
    1.708
    Симпатии:
    3
    Почему "какое-нибудь" ? Именно указанное будет весьма кстати :)
     
  15. unknown181538

    unknown181538 НеГуру
    1C Team

    Регистрация:
    28 дек 2008
    Сообщения:
    1.418
    Симпатии:
    0
    Тут зависит от того, какой частью тела он работает.
     
  16. vbs

    vbs Well-Known Member

    Регистрация:
    18 фев 2007
    Сообщения:
    1.708
    Симпатии:
    3
    Да ясно, какой. На 8-ю букву называется.
     
Загрузка...

Поделиться этой страницей