Загрузка Dbf-файлов с длиной имени больше 8 символов (1С 7.7)

Тема в разделе "1C и всё что с ней связано", создана пользователем BBDragon, 16 фев 2010.

  1. BBDragon

    BBDragon Well-Known Member

    Регистрация:
    4 май 2008
    Сообщения:
    148
    Симпатии:
    0
    В программе необходимо загружать DBF-файлы с длиной имени больше 8 символов. Если длина <=8 символам - все нормально, если же больше - программа вылетает с ошибками:

    ДБФ.Первая(); : Перед выполнением операции нужно открыть базу!
    Пока ДБФ.ВКонце() = 0 Цикл : Перед выполнением операции нужно открыть базу!

    При этом я принудительно обрезаю имя файла до первых 8 символов - но все равно не помогает! Никак не могу понять свою ошибку(

    Код ( (Unknown Language)):
    Процедура ВыборФайла()

    КаталогЗагрузки = "";
    ФайлЗагрузки = "";
    Если ФС.ВыбратьФайл(1, ФайлЗагрузки, КаталогЗагрузки, "Выберите файл", "*.dbf|*.dbf", , ) = 1 Тогда
    ФайлЗагрузки = КаталогЗагрузки + ФайлЗагрузки;
    КонецЕсли;

    КонецПроцедуры   

    Процедура ПриВыбореИмениФайла()
    Поз=Найти(ФайлЗагрузки,".");
    Если (Поз=0) Или (Поз>8) Тогда
    ФайлЗагрузки=СокрП(Лев(СокрЛ(ФайлЗагрузки),12))+".DBF";
    Иначе 
    ФайлЗагрузки=СокрЛП(Лев(ФайлЗагрузки,Поз)+"DBF");
    КонецЕсли;
    КонецПроцедуры  


    Процедура Сформировать()

    ИмФайл=СокрЛП(Лев(СокрЛ(ФайлЗагрузки),8))+".DBF";
    Док1 = СоздатьОбъект("Документ.РеестрСчетовВходящий");  
    ДБФ = СоздатьОбъект("XBase");
    ДБФ.ОткрытьФайл(ИмФайл,,1);
    Док1.Новый();
    ДБФ.Первая(); // первая ошибка
    Пока ДБФ.ВКонце() = 0 Цикл //вторая ошибка
    Док1.НоваяСтрока();
     
  2. Hryv

    Hryv Гость

    А зачем имя обрезать?

    Разве длинные имена XBase не открывает?
    В любом случае имя DOS это не первые 8 символов имени. Там более сложно. Подробностей не расскажу, потому что не знаю
     
  3. BBDragon

    BBDragon Well-Known Member

    Регистрация:
    4 май 2008
    Сообщения:
    148
    Симпатии:
    0
    Вообще-то не открывает) Есть тема про переименовывание файлов DBF:
    http://codeby.net/index.php?showtopic=19491

    Пробовал делать аналогичным образом - тоже не получается(
     
  4. Hryv

    Hryv Гость

    Если допустимо переименовать файл перед открытием, то тем или иным способом его переименовать можно, а потом уже открывать

    Какой способ переименования пробуешь?
     
  5. BBDragon

    BBDragon Well-Known Member

    Регистрация:
    4 май 2008
    Сообщения:
    148
    Симпатии:
    0
    Вообще необходимо чтобы программа без проблем открывала DBF-файлы с длиной имени порядка 8-16 символов. Вот только имя файла я узнаю уже после его открытия (пользователь сам выбирает его в стандартном диалоге).. Как бы сделать так, чтобы:

    1) открыть файл;
    2) переименовать его имя до 8 символов;
    3) дальнейшая обработка
     
  6. hosm

    hosm * so what *

    Регистрация:
    18 май 2009
    Сообщения:
    2.450
    Симпатии:
    7
    А зачем такие сложности?
    нельзя ли не переименовывать, а использовать короткие пути/имена (если, конечно, те не отключены)?
    вот так можно получить короткое имя на ВБ (мсдн)
    <div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">вот что выдал поиск:</div></div><div class="sp-body"><div class="sp-content">решение отсюда:
    Код (Text):
    Процедура Выполнить()
    ДлинныйПуть = "C:\Documents and Settings\1.txt";
    Фо = СоздатьОбъект("Scripting.FileSystemObject");
    Фл = Фо.GetFile(ДлинныйПуть);
    КороткийПуть = Фл.ShortPath;
    Фл = "";
    Фо = "";
    Сообщить(КороткийПуть);
    КонецПроцедуры
    в 1с 8.1 примерно так
    Код (Text):
    FileSystemObject=Новый COMObject("Scripting.FileSystemObject");
    FileName= FileSystemObject.getFile(LongPath).ShortPath;
    Или WinApi - поиск по getshortpathname

    Добавлено:
    переименовать можно ДО открытия, Вам же сказали.
    т.е. правильно мыслить в таком направлении:
    1) дать пользователю выбрать файл.
    2) переименовать в 8.3-формат или получить короткое имя из длинного (как написано выше)
    3) открыть и сделать нужную обработку
     
  7. Hryv

    Hryv Гость

    Честно говоря, я и не подозревал, что так просто можно получить короткое имя
    Это все меняет
    Я бы так и сделал

    Кстати, переименование еще может и не прокатить, если проблема не только в имени, но и в пути
    Получить короткое имя - лучшее решение
     
  8. BBDragon

    BBDragon Well-Known Member

    Регистрация:
    4 май 2008
    Сообщения:
    148
    Симпатии:
    0
    Спасибо за помощь! Но у меня ошибка в строчке:

    Фл = Фо.GetFile(ДлинныйПуть);

    То же самое и по указанной Вами ссылке :)


    Я неправильно выразился, имелось в виду дать возможность выбрать пользователю файл (пункт №1 у вас) :)
     
  9. hosm

    hosm * so what *

    Регистрация:
    18 май 2009
    Сообщения:
    2.450
    Симпатии:
    7
    я пробовала давно не в 1с, вроде через апи получалось, уже не помню.
    сейчас можно тут почитать
    http://msdn.microsoft.com/en-us/library/aa..._vs._long_names
    тут попробовать
    http://msdn.microsoft.com/en-us/library/aa364989(VS.85).aspx
    если язык нормально поддерживает декларации из виндозных либ.
    там еще указание есть насчет CharSet, похоже, из-за русских символов что-то может глючить.
    если не поможет - таки переименовывать... :)

    Добавлено: и можно настроить, что система короткие имена не поддерживает... возможно, из-за этого и не получается
     
  10. BBDragon

    BBDragon Well-Known Member

    Регистрация:
    4 май 2008
    Сообщения:
    148
    Симпатии:
    0
    К сожалению данный метод тоже не подходит, ибо функция GetShortPathName 1С 7.7 незнакома(

    Ради интереса попробовал переименовать уже закрытый файл в файл с длиной имени более 8 символов.

    [codebox]
    ДБФ.ЗакрытьФайл(); //закрываем наш обработанный DBF-файл
    ФС.УстТекКаталог(СокрЛП("D:"));
    Результат = "";
    Результат = ФС.НайтиПервыйФайл("reestr.DBF");
    Если Результат<>"" Тогда
    ФС.ПереименоватьФайл(СокрЛП(КаталогЗагрузки)+"\"+ Результат,СокрЛП (КаталогЗагрузки)+"\R91000" + Результат,1);
    КонецЕсли;
    [/codebox]

    Программа находит файл "D:\reestr.DBF" и переименовывает его в "D:\R91000reestr.dbf". Теперь необходимо сделать следующее:

    1) позволить пользователю выбрать файл;
    2) обрезать его имя до первых 8 символов;
    3) обработать и закрыть;
    4) переименовать полученный файл так как нужно.

    Имя исходного файла значения не имеет, главное, чтобы это был DBF-файл (все необходимые параметры берутся из данных самого файла). Пробовал обрезать имя файла, переименовывать его - все тщетно! Ну никак не получается это сделать(
     
  11. hosm

    hosm * so what *

    Регистрация:
    18 май 2009
    Сообщения:
    2.450
    Симпатии:
    7
    А файл-то есть на диске в момент переименования? никем не открыт? что за ошибка?
    по ходу смутила 1 у Вас:
    <ТипДиалога> -: 0 - диалог типа <открыть>, 1 - диалог типа <сохранить>;
    инфа отсюда http://mista.ru/tutor_1c/file.htm
    Есть проверки на наличие файла и если файла нет, смотрите тут вариант создания http://1c-pro.ru/lofiversion/index.php/t12935.html
    и даже пример копирования файла есть
     
  12. BBDragon

    BBDragon Well-Known Member

    Регистрация:
    4 май 2008
    Сообщения:
    148
    Симпатии:
    0
    OKEN, спасибо огромное за помощь! Я тоже заметил эту ошибку, но потом почему-то забыл про нее.. Сейчас временно оставил этот пункт, ибо возникли более важные задачи. Попозже я еще к нему вернусь :)
     
  13. KiR

    KiR НЕ шибка опытный програмер)
    1C Team

    Регистрация:
    11 сен 2007
    Сообщения:
    1.581
    Симпатии:
    0
    Да, при таком типе диалога еще нужны права на изменение файла....
     
  14. BBDragon

    BBDragon Well-Known Member

    Регистрация:
    4 май 2008
    Сообщения:
    148
    Симпатии:
    0
    Наконец-то разделался с другими делами и появилась возможность заняться этим вопросом. Пробую диалог типа <открыть> - файл все равно не открывается( Вся проблема в том, что файлы которые необходимо обрабатывать имеют формат DBF, но длина имени составляет порядка 12-14 символов. Неужели нет никакой возможности открыть их без предварительного переименовывания?
     
  15. vitfil

    vitfil IT-интегратор

    Регистрация:
    2 апр 2004
    Сообщения:
    2.070
    Симпатии:
    0
    Для какого банана, извиняюсь, переименовывать?
    При длинном пути надо брать либо в кавычки имя файла, либо, ИмяФайла = Лев(ДлинноеИмяФайла,7)+"~.dbf"
     
  16. vbs

    vbs Well-Known Member

    Регистрация:
    18 фев 2007
    Сообщения:
    1.708
    Симпатии:
    3
    Еще раз убедился, что старая привычка (имя файла латиницей и не более 8 символов) позволяет избежать массы проблем.
    Наследство DOS 6.2 все еще живо в народных сердцах :)
     
  17. BBDragon

    BBDragon Well-Known Member

    Регистрация:
    4 май 2008
    Сообщения:
    148
    Симпатии:
    0
    Поясню подробней. На диске в различных каталогах находятся файлы dbf с длиной имени порядка 12-14 символов. Если длина имени не превышает 8 символов- файлы открываются нормально, если же больше - программа вылетает с ошибкой "Перед выполнением операции нужно открыть базу!" на строчках
    ДБФ.Первая();
    и Пока ДБФ.ВКонце() = 0 Цикл

    Хотелось бы программно переименовывать длинные имена до 8 символов, обрабатывать данные, а затем возвращать исходное имя файлам. В противном случае остается только вручную переименовывать файлы, что весьма неудобно, ибо их несколько сотен и каждый день появляются новые.


    Первоначальная версия процедур:

    [codebox]
    Процедура ВыборФайла()

    КаталогЗагрузки = "";
    ФайлЗагрузки = "";
    Если ФС.ВыбратьФайл(1, ФайлЗагрузки, КаталогЗагрузки, "Выберите файл", "*.dbf|*.dbf", , ) = 1 Тогда
    ФайлЗагрузки = КаталогЗагрузки + ФайлЗагрузки;
    КонецЕсли;

    КонецПроцедуры

    Процедура ПриВыбореИмениФайла()
    Поз=Найти(ФайлЗагрузки,".");
    Если (Поз=0) Или (Поз>8) Тогда
    ФайлЗагрузки=СокрП(Лев(СокрЛ(ФайлЗагрузки),12))+".DBF";
    Иначе
    ФайлЗагрузки=СокрЛП(Лев(ФайлЗагрузки,Поз)+"DBF");
    КонецЕсли;
    КонецПроцедуры


    Процедура Сформировать()

    ИмФайл=СокрЛП(ФайлЗагрузки);
    Док1 = СоздатьОбъект("Документ.РеестрСчетовВходящийЛПУ");
    ДБФ = СоздатьОбъект("XBase");
    ДБФ.ОткрытьФайл(ИмФайл,,1);
    Док1.Новый();
    ДБФ.Первая();
    Пока ДБФ.ВКонце() = 0 Цикл
    Док1.НоваяСтрока();
    // и т.д.
    [/codebox]


    Решил сделать возможной загрузку файлов и с длинными именами. Алгоритм следующий:
    1) long = 0;
    2) пытаемся открыть файл, если длина больше 8 символов Тогда
    а) усекаем имя до 8 символов;
    б) переименовываем файл на диске в короткое имя;
    в) присваиваем переменной long значение 1;
    Иначе
    ничего не делаем
    Далее создаем объект типа XBase, создаем новый документ, открываем наш файл DBF и начинаем заполнять документ значениями полей файла. Если у нас был длинный файл (long=1), то после окончания всех действий вновь переименовываем файл (возвращаем ему исходное имя).


    [codebox]
    Перем КороткоеИмяФайла,ПолноеИмяФайла;
    Процедура ВыборФайла()

    КаталогЗагрузки = "";
    ФайлЗагрузки = "";
    Если ФС.ВыбратьФайл(0, ФайлЗагрузки, КаталогЗагрузки, "Выберите файл", "*.dbf|*.dbf", , ) = 1 Тогда
    ПолноеИмяФайла = КаталогЗагрузки + ФайлЗагрузки;
    КонецЕсли;

    КонецПроцедуры

    Процедура ПриВыбореИмениФайла()
    long=0;
    Поз=Найти(ФайлЗагрузки,".");
    Если (Поз>8) Тогда // длинное имя файла
    КороткоеИмяФайла=СокрП(Лев(СокрЛ(ФайлЗагрузки),8))+".DBF";;
    long = 1;
    ФС.УстТекКаталог(КаталогЗагрузки);
    Результат = "";
    Результат = ФС.НайтиПервыйФайл(ФайлЗагрузки);
    Если Результат<>"" Тогда
    ФС.ПереименоватьФайл(СокрЛП(КаталогЗагрузки)+"\"+ Результат,СокрЛП (КаталогЗагрузки)+"\" + КороткоеИмяФайла,1);//теперь наш файл называется R91000.dbf
    КонецЕсли;
    Иначе
    КороткоеИмяФайла=СокрЛП(Лев(ФайлЗагрузки,Поз)+"DBF");
    КонецЕсли;
    КонецПроцедуры

    Процедура Сформировать()
    ИмФайл=СокрЛП(КороткоеИмяФайла);
    Док1 = СоздатьОбъект("Документ.РеестрСчетовВходящийЛПУ");
    ДБФ = СоздатьОбъект("XBase");
    ФС.УстТекКаталог(КаталогЗагрузки);
    ДБФ.ОткрытьФайл(ИмФайл,,1);
    Док1.Новый();
    ДБФ.Первая();
    Пока ДБФ.ВКонце() = 0 Цикл
    Док1.НоваяСтрока();
    //и т.д.
    [/codebox]

    В новом варианте обработка файлов с длинными именами все равно невозможна, программа вылетает с теми же ошибками. Подскажите, возможно ли реализовать мою задумку в 1С?
     
  18. vbs

    vbs Well-Known Member

    Регистрация:
    18 фев 2007
    Сообщения:
    1.708
    Симпатии:
    3
    Пока только безумная гипотеза : А что если попробовать открыть файл с помощью Excel ?
     
  19. BBDragon

    BBDragon Well-Known Member

    Регистрация:
    4 май 2008
    Сообщения:
    148
    Симпатии:
    0
    Открывать файл мне нужно в программе на базе 1С, чтобы загружать данные в документы. Не совсем понял при чем тут Excel :)
     
  20. vbs

    vbs Well-Known Member

    Регистрация:
    18 фев 2007
    Сообщения:
    1.708
    Симпатии:
    3
    Excel.Application использовать как средство в среде 1С
    DBF-файлы с длинными именами Excel прекрасно открывает, если явно указать расширение .DBF

    А обработку легко адаптировать, просматривая строки файла как в Excel
     
Загрузка...

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