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

  • Автор темы BBDragon
  • Дата начала
B

BBDragon

В программе необходимо загружать DBF-файлы с длиной имени больше 8 символов. Если длина <=8 символам - все нормально, если же больше - программа вылетает с ошибками:

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

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

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

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

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

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


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

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

Hryv

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

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

BBDragon

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

Разве длинные имена XBase не открывает?
В любом случае имя DOS это не первые 8 символов имени. Там более сложно. Подробностей не расскажу, потому что не знаю
Вообще-то не открывает) Есть тема про переименовывание файлов DBF:
link removed

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

Hryv

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

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

BBDragon

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

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

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

hosm

А зачем такие сложности?
нельзя ли не переименовывать, а использовать короткие пути/имена (если, конечно, те не отключены)?

<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">
Код:
Процедура Выполнить() 
ДлинныйПуть = "C:\Documents and Settings\1.txt";
Фо = СоздатьОбъект("Scripting.FileSystemObject");
Фл = Фо.GetFile(ДлинныйПуть);
КороткийПуть = Фл.ShortPath;
Фл = "";
Фо = "";
Сообщить(КороткийПуть); 
КонецПроцедуры
в 1с 8.1 примерно так
Код:
FileSystemObject=Новый COMObject("Scripting.FileSystemObject");
FileName= FileSystemObject.getFile(LongPath).ShortPath;
Или WinApi - поиск по getshortpathname

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

Hryv

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

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

BBDragon

А зачем такие сложности?
нельзя ли не переименовывать, а использовать короткие пути/имена (если, конечно, те не отключены)?

<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">
Код:
Процедура Выполнить() 
ДлинныйПуть = "C:\Documents and Settings\1.txt";
Фо = СоздатьОбъект("Scripting.FileSystemObject");
Фл = Фо.GetFile(ДлинныйПуть);
КороткийПуть = Фл.ShortPath;
Фл = "";
Фо = "";
Сообщить(КороткийПуть); 
КонецПроцедуры
в 1с 8.1 примерно так
Код:
FileSystemObject=Новый COMObject("Scripting.FileSystemObject");
FileName= FileSystemObject.getFile(LongPath).ShortPath;
Или WinApi - поиск по getshortpathname

Спасибо за помощь! Но у меня ошибка в строчке:

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

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


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

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

hosm

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

тут попробовать

если язык нормально поддерживает декларации из виндозных либ.
там еще указание есть насчет CharSet, похоже, из-за русских символов что-то может глючить.
если не поможет - таки переименовывать... :)

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

BBDragon

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

тут попробовать

если язык нормально поддерживает декларации из виндозных либ.
там еще указание есть насчет CharSet, похоже, из-за русских символов что-то может глючить.
если не поможет - таки переименовывать... :(

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

К сожалению данный метод тоже не подходит, ибо функция 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-файл (все необходимые параметры берутся из данных самого файла). Пробовал обрезать имя файла, переименовывать его - все тщетно! Ну никак не получается это сделать(
 
H

hosm

Имя исходного файла значения не имеет
А файл-то есть на диске в момент переименования? никем не открыт? что за ошибка?
по ходу смутила 1 у Вас:
<ТипДиалога> -: 0 - диалог типа <открыть>, 1 - диалог типа <сохранить>;
инфа отсюда
Есть проверки на наличие файла и если файла нет, смотрите тут вариант создания
и даже пример копирования файла есть
 
B

BBDragon

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

BBDragon

Наконец-то разделался с другими делами и появилась возможность заняться этим вопросом. Пробую диалог типа <открыть> - файл все равно не открывается( Вся проблема в том, что файлы которые необходимо обрабатывать имеют формат DBF, но длина имени составляет порядка 12-14 символов. Неужели нет никакой возможности открыть их без предварительного переименовывания?
 
V

vitfil

Для какого банана, извиняюсь, переименовывать?
При длинном пути надо брать либо в кавычки имя файла, либо, ИмяФайла = Лев(ДлинноеИмяФайла,7)+"~.dbf"
 
V

vbs

Еще раз убедился, что старая привычка (имя файла латиницей и не более 8 символов) позволяет избежать массы проблем.
Наследство DOS 6.2 все еще живо в народных сердцах :)
 
B

BBDragon

Для какого банана, извиняюсь, переименовывать?
При длинном пути надо брать либо в кавычки имя файла, либо, ИмяФайла = Лев(ДлинноеИмяФайла,7)+"~.dbf"
Поясню подробней. На диске в различных каталогах находятся файлы 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С?
 
V

vbs

Пока только безумная гипотеза : А что если попробовать открыть файл с помощью Excel ?
 
B

BBDragon

Пока только безумная гипотеза : А что если попробовать открыть файл с помощью Excel ?
Открывать файл мне нужно в программе на базе 1С, чтобы загружать данные в документы. Не совсем понял при чем тут Excel :)
 
V

vbs

Не совсем понял при чем тут Excel
Excel.Application использовать как средство в среде 1С
DBF-файлы с длинными именами Excel прекрасно открывает, если явно указать расширение .DBF

А обработку легко адаптировать, просматривая строки файла как в Excel
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!