[РЕШЕНО] DBF, толстый и тонкий клиенты

Тема в разделе "Конфигурирование на платформе "1С:Предприятие 8"", создана пользователем xxx949, 22 янв 2015.

  1. TopicStarter Overlay
    xxx949
    Offline

    xxx949 Опытный в 1С

    Регистрация:
    29 июл 2010
    Сообщения:
    302
    Симпатии:
    1
    Баллы:
    29
    Уважаемые, специалисты!
    Помогите разобраться, ничего не понимаю.

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

    Я к этой процедуре обращаюсь с модуля обычного приложения и с модуля управляемого приложения (ПриНачалеРаботыСистемы()). Так вот ошибка в открытии dbf. В толстый клиент захожу, все нормально, а в тонком не работает.

    Код:
    Файл = Новый XBase;
    Файл.ОткрытьФайл(ФайлПользователей);
    Вот что я заметил, если в тонком клиенте я файл открываю только для чтения, т.е. Файл.ОткрытьФайл(ФайлПользователей,,Истина) - то он открывается нормально и читается, а если для записи, то выходит ошибка о том, что файл должен быть открыт.

    т.е.
    В толстом клиенте:
    все нормально работает

    В тонком клиенте:
    Файл.ОткрытьФайл(ФайлПользователей,,Истина);
    Результат: Файл.Открыта() = Истина
    Все нормально читает.

    Файл.ОткрытьФайл(ФайлПользователей);
    Результат: Файл.Открыта() = Ложь
    Файл получается не открыт, запись в результате не возможна, выходит ошибка.

    Спасибо
  2. nomad_irk
    Offline

    nomad_irk Гуру в 1С

    Регистрация:
    20 окт 2008
    Сообщения:
    7.554
    Симпатии:
    716
    Баллы:
    204
    База в файловом режиме работает?
  3. TopicStarter Overlay
    xxx949
    Offline

    xxx949 Опытный в 1С

    Регистрация:
    29 июл 2010
    Сообщения:
    302
    Симпатии:
    1
    Баллы:
    29
    Нет SQL
    --- Объединение сообщений, 22 янв 2015 ---
    вот код на всякий случай, т.е. сначала происходит чтение (dbf открывается в режиме только для чтения) - это проходит нормально, файл читается, затем происходит запись (файл в этот момент получается не открыт).

    Код:
    Процедура ВыполнитьЗаписьВФайл() Экспорт
       
        ИмяФайла          = "ListUser.dbf";
       
        ФайлПользователей = Константы.яПутьЛог.Получить() + ИмяФайла;
        Если НЕ ФайлСуществует(ФайлПользователей) Тогда
            Файл = СоздатьФайл(ФайлПользователей);
        КонецЕсли;
       
        //откроем только для чтения
        Если ФайлСуществует(ФайлПользователей) Тогда
            Файл = Новый XBase;
            Файл.ОткрытьФайл(ФайлПользователей,,Истина);
        КонецЕсли;
       
        // создадим временную таблицу пользователей из dbf
        ВременнаяТаблица = Новый ТаблицаЗначений;
        ВременнаяТаблица.Колонки.Добавить("Пользователь");
        ВременнаяТаблица.Колонки.Добавить("Компьютер");
        ВременнаяТаблица.Колонки.Добавить("ПоследняяАктивность");
        ВременнаяТаблица.Колонки.Добавить("База");
       
        // выгрузим из dbf пользователей во временную таблицу
        Файл.Первая();
        Пока НЕ Файл.ВКонце() Цикл
            НоваяСтрока = ВременнаяТаблица.Добавить();
            НоваяСтрока.Пользователь = СокрЛП(Файл.USER);
            НоваяСтрока.Компьютер = СокрЛП(Файл.COMP);
            НоваяСтрока.ПоследняяАктивность = СокрЛП(Файл.LAST_ACT);
            НоваяСтрока.База = СокрЛП(Файл.BASE);
            Файл.Следующая();
        КонецЦикла;
       
        // сверим пользователя со временной таблицей изменим существующего или добавим нового
        ПользовательНайденИИзменен = Ложь;
        Для Каждого ВременнаяСтрока Из ВременнаяТаблица Цикл
            Если СокрЛП(ПараметрыСеанса.ТекущийПользователь.Код) = ВременнаяСтрока.Пользователь И ИмяБазы = ВременнаяСтрока.База Тогда
                ВременнаяСтрока.Компьютер = ИмяКомпьютера();
                СтрокаДаты = Строка(Формат(ТекущаяДата(), "ДФ=гггг")) +
                     Строка(Формат(ТекущаяДата(), "ДФ=ММ")) +
                     Строка(Формат(ТекущаяДата(), "ДФ=дд")) +
                     Строка(Формат(ТекущаяДата(), "ДФ=ЧЧ")) +
                     Строка(Формат(ТекущаяДата(), "ДФ=мм")) +
                     Строка(Формат(ТекущаяДата(), "ДФ=сс"));
                ВременнаяСтрока.ПоследняяАктивность = СтрокаДаты;
                ПользовательНайденИИзменен = Истина;
                Прервать;
            КонецЕсли;
        КонецЦикла;
        Если НЕ ПользовательНайденИИзменен Тогда
            НоваяСтрока = ВременнаяТаблица.Добавить();
            НоваяСтрока.Пользователь = СокрЛП(ПараметрыСеанса.ТекущийПользователь.Код);
            НоваяСтрока.Компьютер = ИмяКомпьютера();
            СтрокаДаты = Строка(Формат(ТекущаяДата(), "ДФ=гггг")) +
                 Строка(Формат(ТекущаяДата(), "ДФ=ММ")) +
                 Строка(Формат(ТекущаяДата(), "ДФ=дд")) +
                 Строка(Формат(ТекущаяДата(), "ДФ=ЧЧ")) +
                 Строка(Формат(ТекущаяДата(), "ДФ=мм")) +
                 Строка(Формат(ТекущаяДата(), "ДФ=сс"));
            НоваяСтрока.ПоследняяАктивность = СтрокаДаты;
            НоваяСтрока.База = ИмяБазы;
        КонецЕсли;
       
        Файл.ЗакрытьФайл();
       
        //откроем файл для записи
        Если ФайлСуществует(ФайлПользователей) Тогда
            Файл = Новый XBase;
            Файл.ОткрытьФайл(ФайлПользователей);
        КонецЕсли;
       
        Файл.ОчиститьФайл();
       
        Для Каждого Строка Из ВременнаяТаблица Цикл
           
            Если НЕ СокрЛП(Строка.Пользователь) = "" Тогда
                Файл.Добавить();
                Файл.USER = СокрЛП(Строка.Пользователь);
                Файл.COMP = СокрЛП(Строка.Компьютер);
                Файл.LAST_ACT = СокрЛП(Строка.ПоследняяАктивность);
                Файл.BASE = СокрЛП(Строка.База);
                Файл.Записать();
            КонецЕсли;
           
        КонецЦикла;
       
        Файл.ЗакрытьФайл();
       
    КонецПроцедуры
    Последнее редактирование: 22 янв 2015
  4. nomad_irk
    Offline

    nomad_irk Гуру в 1С

    Регистрация:
    20 окт 2008
    Сообщения:
    7.554
    Симпатии:
    716
    Баллы:
    204
    В качестве предположения: после того, как почитали файл, его необходимо закрыть.
  5. TopicStarter Overlay
    xxx949
    Offline

    xxx949 Опытный в 1С

    Регистрация:
    29 июл 2010
    Сообщения:
    302
    Симпатии:
    1
    Баллы:
    29
    Он каждый раз закрывается, в коде это видно
  6. shurikvz
    Online

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    Исключение при открытии файла на запись происходит?
    А сколько пользователей одновременно 1С запускают? Я к тому что если из какого-то сеанса файл открыт на чтение, то в тот же момент времени его на запись открыть не получится.
  7. Svb
    Online

    Svb Опытный в 1С Команда форума

    Регистрация:
    12 янв 2011
    Сообщения:
    980
    Симпатии:
    19
    Баллы:
    29
    Может прав нет?
    В тонком клиенте процедура ВыполнитьЗаписьВФайл() выполняется на сервере или на клиенте?
    xxx949 нравится это.
  8. nomad_irk
    Offline

    nomad_irk Гуру в 1С

    Регистрация:
    20 окт 2008
    Сообщения:
    7.554
    Симпатии:
    716
    Баллы:
    204
    Код:
    &НаКлиенте
    Процедура Команда1(Команда)
    
         ОбработатьФайлБД();
       
    КонецПроцедуры
    
    &НаСервере
    Процедура ОбработатьФайлБД()
       
        ИмяФайла          = "D:\ListUser.dbf";
      
        ФайлПользователей = ИмяФайла;
       
        ТекФайл = Новый Файл(ФайлПользователей);
       
        Если НЕ ТекФайл.Существует() Тогда
            СоздатьФайлНаСервере(ФайлПользователей);
        КонецЕсли;
       
        //откроем только для чтения
        Если ТекФайл.Существует() Тогда
            Файл = Новый XBase;
            Файл.ОткрытьФайл(ФайлПользователей,,Истина);
        КонецЕсли;
      
        // создадим временную таблицу пользователей из dbf
        ВременнаяТаблица = Новый ТаблицаЗначений;
        ВременнаяТаблица.Колонки.Добавить("Пользователь");
        ВременнаяТаблица.Колонки.Добавить("Компьютер");
        ВременнаяТаблица.Колонки.Добавить("ПоследняяАктивность");
        ВременнаяТаблица.Колонки.Добавить("База");
      
        // выгрузим из dbf пользователей во временную таблицу
        Файл.Первая();
        Пока НЕ Файл.ВКонце() Цикл
            НоваяСтрока = ВременнаяТаблица.Добавить();
            НоваяСтрока.Пользователь = СокрЛП(Файл.USER);
            НоваяСтрока.Компьютер = СокрЛП(Файл.COMP);
            НоваяСтрока.ПоследняяАктивность = СокрЛП(Файл.LAST_ACT);
            НоваяСтрока.База = СокрЛП(Файл.BASE);
            Файл.Следующая();
        КонецЦикла;
          
        Файл.ЗакрытьФайл();
      
        //откроем файл для записи
        Если ТекФайл.Существует() Тогда
            Файл = Новый XBase;
            Файл.ОткрытьФайл(ФайлПользователей);
        КонецЕсли;
      
        Файл.ОчиститьФайл();
      
        //Для Каждого Строка Из ВременнаяТаблица Цикл
          
            //Если НЕ СокрЛП(Строка.Пользователь) = "" Тогда
                Файл.Добавить();
                Файл.USER = "USER";
                Файл.COMP = "COMP";
                Файл.LAST_ACT = "LastActivity";
                Файл.BASE = "Base";
                Файл.Записать();
            //КонецЕсли;
          
        //КонецЦикла;
      
        Файл.ЗакрытьФайл();
       
    КонецПроцедуры
    
    &НаСервереБезКонтекста
    Процедура СоздатьФайлНаСервере(ФайлПользователя)
       
        ТекФайл = Новый XBASE;
        ТекФайл.поля.Добавить("USER", "S", 30);
        ТекФайл.поля.Добавить("COMP", "S", 30);
        ТекФайл.поля.Добавить("LAST_ACT", "S", 30);
        ТекФайл.поля.Добавить("BASE", "S", 30);
        ТекФайл.СоздатьФайл(ФайлПользователя);
        ТекФайл.ЗакрытьФайл();
       
    КонецПроцедуры
    Склоняюсь к версии, озвученной shurikvz: несколько пользователей пытаются терзать один и тот же файл в разных режимах.
    В однопользовательском режиме все отрабатывает без ошибок.
  9. TopicStarter Overlay
    xxx949
    Offline

    xxx949 Опытный в 1С

    Регистрация:
    29 июл 2010
    Сообщения:
    302
    Симпатии:
    1
    Баллы:
    29
    Эта версия отпадает, я работаю в отладочной базе, в ней кроме меня никто не работает.
    --- Объединение сообщений, 22 янв 2015 ---
    Вот этот ответ мне ближе, теперь как бы с этим разобраться. Процедура отрабатывается на клиенте, я тоже об этом подумал, но как мне ее переписать на сервер?

    Процедура ВыполнитьЗаписьВФайл() лежит в общем модуле.

    Кстати, для информации, сейчас подумал и решил переписать запись в DBF файл, т.е. вместо DBF пишу в XML. Ситуация точно такая же, только теперь он пишет, что нет доступа к файлу.

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

    Поставил перед процедурой &НаСервере - не помогло.
    Последнее редактирование: 22 янв 2015
  10. nomad_irk
    Offline

    nomad_irk Гуру в 1С

    Регистрация:
    20 окт 2008
    Сообщения:
    7.554
    Симпатии:
    716
    Баллы:
    204
    Клиент работает со своими правами, а код на сервере выполняется с правами той учетной записи, под которой запущен сервис на сервере 1С.
    Вероятно, как уже заметили, проблема в правах доступа к общим ресурсам и файлам в частности.
    xxx949 нравится это.
  11. TopicStarter Overlay
    xxx949
    Offline

    xxx949 Опытный в 1С

    Регистрация:
    29 июл 2010
    Сообщения:
    302
    Симпатии:
    1
    Баллы:
    29
    Вот здесь огромное человеческое спасибо, все получилось, у меня сервер был запущен с локальными правами, поменял права и все заработало.
    --- Объединение сообщений, 22 янв 2015 ---
    Всем большое спасибо, проблема решена.

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