выгрузка на ftp в сервисе (web)

1. Docaru 1 10.12.20 18:42 Сейчас в теме
Добрый день, коллеги. Крайне редко обращаюсь за помощью, но вот тут беда прям. Весь мозг сломал - поможите чем можите!
Задача: есть расширение для БП 3.0 в сервисе 1С Фреш. Создается dbf (не кидайте тапками - ТЗ клиента) и он должен копироваться на ftp. Тестирую у себя на клиент-сервере (SQL) - все работает как часы. Отправялю на аудит, все загружается к клиенту, а у него уже при выгрузке пишет дичь:
Обработка: Обработка выгрузки на ftp: Ошибка подключения к FTP-серверу, проверьте правильность задания пути и права доступа к ресурсу.
Файл не обнаружен '/temp/v8_fCb9XW_1/Price.dbf'
{чдв_ОбменСАптекой Обработка.ОбменПоFTP_БП_ЧДВ.Форма.Форма.Форма(180)}: FTPСоединение.Записать(ПолучитьИзВременногоХранилища(АдресВХ), ПутьДляПрайса + "Price.dbf");

по причине:
Файл не обнаружен '/temp/v8_fCb9XW_1/Price.dbf'

Код процедуры:
&НаСервере
Функция  ВыгрузитьПрайсНаСервере()
	КаталогВФ = ФайловаяСистема.СоздатьВременныйКаталог();
	ИмяФайла = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку("%1Price.dbf",КаталогВФ);
	
	ФайлПрайс = Новый XBase;
	ФайлПрайс.Кодировка = КодировкаXBase.OEM;
	ФайлПрайс.поля.Добавить("CODEPST","S",36,0);
	ФайлПрайс.поля.Добавить("NAME","S",200,0);
	ФайлПрайс.поля.Добавить("CNTR","S",100,0);
	ФайлПрайс.поля.Добавить("FIRM","S",150,0);
	ФайлПрайс.поля.Добавить("QNTPACK","N",10,0);
	ФайлПрайс.поля.Добавить("EAN13","S",13,0);
	ФайлПрайс.поля.Добавить("GDATE","D",8,0);
	ФайлПрайс.поля.Добавить("QNT","N",8,0);
	ФайлПрайс.поля.Добавить("PRICE","N",10,2);
	ФайлПрайс.поля.Добавить("RATEPACK","N",10,0);
	ФайлПрайс.СоздатьФайл(ИмяФайла);
	ФайлПрайс.Записать();
	Для каждого Строка Из ТЗПрайс Цикл
		
		ФайлПрайс.Добавить();
		ЗаполнитьЗначенияСвойств(ФайлПрайс,Строка);	
		Если Не Строка.ЦенаВключаетНДС Тогда
			СтавкаНДС = СтавкаНДСНаСервере(Строка.ВидСтавкиНДС);
			ЗначениеСтавкиНДС = УчетНДСВызовСервераПовтИсп.ПолучитьСтавкуНДС(СтавкаНДС, Ложь);
			ФайлПрайс.PRICE   = Строка.PRICE * (1 + ЗначениеСтавкиНДС / 100);
		КонецЕсли;
		ФайлПрайс.Записать();
	КонецЦикла; 
	АдресВХПрайс = ПоместитьВоВременноеХранилище(ИмяФайла);
	ФайлПрайс.ЗакрытьФайл();
	//Поток = Новый ФайловыйПоток(ИмяФайла, РежимОткрытияФайла.Открыть, ДоступКФайлу.Чтение);
	Попытка
		FTPСоединение = ПолучитьFTPСоединение();
	Исключение
		ТекстОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ПолучитьСообщениеОбОшибке(102);
		ДополнитьСообщениеОбОшибке(ТекстОшибки);
		Возврат Ложь;
		
	КонецПопытки;
	
	Попытка
Показать

FTPСоединение.Записать(ПолучитьИзВременногоХранилища(АдресВХПрайс), ПутьДляПрайса + "Price.dbf");
//FTPСоединение.Записать(ПутьДляПрайса + "Price.dbf",Поток);
	Исключение
		ТекстОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ПолучитьСообщениеОбОшибке(103);
		ДополнитьСообщениеОбОшибке(ТекстОшибки);
		Возврат Ложь;
	КонецПопытки;
	
	Попытка
		МассивФайлов = FTPСоединение.НайтиФайлы(ПутьДляПрайса, "Price.dbf", Ложь);
	Исключение
		ТекстОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ПолучитьСообщениеОбОшибке(104);
		ДополнитьСообщениеОбОшибке(ТекстОшибки);
		Возврат Ложь;
	КонецПопытки;
	ФайловаяСистема.УдалитьВременныйКаталог(КаталогВФ);
	Возврат МассивФайлов.Количество() > 0;
КонецФункции
Показать

ЧЯДНТ?!
По теме из базы знаний
Вознаграждение за ответ
Показать полностью
Найденные решения
48. uno-c 238 10.12.20 22:25 Сейчас в теме +10 $m
В общем, мои рекомендации - сделать
ИмяФайла = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку("%1PRICE.DBF",КаталогВФ);
- т.е. "PRICE.DBF" - полностью верхний регистр. Если xbase помнит старинные правила 8.3 - то там и регистр только верхний когда-то был )
support; Docaru; unknow_user; user1503726; +4 Ответить
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. Tiger77 69 10.12.20 19:07 Сейчас в теме
Проблема в функциях

АдресВХПрайс = ПоместитьВоВременноеХранилище(ИмяФайла);


и

ПолучитьИзВременногоХранилища(АдресВХПрайс)


ты в хранилище сохраняешь не сам файл, а его имя.
unknow_user; +1 Ответить
3. Docaru 1 10.12.20 19:24 Сейчас в теме
(2) ну во-первых повторюсь - клиент-сервере все работает, а во вторых - я изначально писал так:
FTPСоединение.Записать(ИмяФайла, ПутьДляПрайса + "Price.dbf");
ошибка была та же - файла типа нет...
4. Docaru 1 10.12.20 19:34 Сейчас в теме
последняя попытка была сделана через файловый поток
Поток = Новый ФайловыйПоток(ИмяФайла, РежимОткрытияФайла.Открыть, ДоступКФайлу.Чтение);
FTPСоединение.Записать(ПутьДляПрайса + "Price.dbf",Поток);
на что аудиторы написали следуюущее:
Замечания:
1. В сервисе используется клиент-серверный вариант работы. Клиент и сервер находятся на разных компьютерах. Чтение/запись файла, выбранного на клиенте (либо чтение/запись в каталог, выбранный на клиенте), невозможно на сервере.
При работе на стороне сервера для работы с файлами в безопасном режиме, вам доступен только каталог временных файлов.

FTPСоединение.Записать(Источник, Приемник)
Просьба указывать правильный путь к копируемому файлу.

вообще не понял...
5. Tiger77 69 10.12.20 19:39 Сейчас в теме
Если у вас на компьютере А (Клиенте) есть файл /temp/v8_fCb9XW_1/Price.dbf
то это не означает что на компьютере B (Сервере) он тоже будет

Его нужно туда скопировать. Передавать через временное хранилище нужно ДвоичыеДанные, а не имя файла!

На SQL работает, так как Компьютер А = Компьютер B
unknow_user; +1 Ответить
6. Docaru 1 10.12.20 19:50 Сейчас в теме
(5)вы видите, что у меня все в одной функциии на сервере? у меня нет передачи на клиент файла.
7. support 4450 10.12.20 20:23 Сейчас в теме
Помогите коллеге!
8. user1503726 10.12.20 20:34 Сейчас в теме
А что в этом ftp соединении до записи файла в свойствах есть? Просто по синтакас помощнику все подряд...
unknow_user; +1 Ответить
9. Docaru 1 10.12.20 20:37 Сейчас в теме
(8)вы про это?
&НаСервере
Функция ПолучитьFTPСоединение()
	
	НастройкиFTP = ОбменДаннымиСервер.FTPНастройкиСоединения();
	НастройкиFTP.Сервер               = "supp.****.ru";
	НастройкиFTP.ИмяПользователя      = "****";
	НастройкиFTP.ПарольПользователя   = "*****";
	НастройкиFTP.ЗащищенноеСоединение = Неопределено;
	
	Возврат ОбменДаннымиСервер.FTPСоединение(НастройкиFTP);
	
КонецФункции
Показать
unknow_user; +1 Ответить
10. user1503726 10.12.20 20:42 Сейчас в теме
Да, про это.Вы не допускаете, что ftp соединение без опции защищенное соединение на компьютере клиента может не быть установлено или установлено, но не позволять каких-то конкретных действий?
Я в данном случае просто как пример..
unknow_user; +1 Ответить
11. Docaru 1 10.12.20 20:44 Сейчас в теме
(10)было такое предположение, но запись
НастройкиFTP.ЗащищенноеСоединение = Неопределено;

сделана специально - функция ОбменДаннымиСервер.FTPСоединение(НастройкиFTP) возвращает НастройкиПроксиСервера(Настройки.ЗащищенноеСоединение) ftp:
Функция НастройкиПроксиСервера(ЗащищенноеСоединение)
	
	Прокси = Неопределено;
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ПолучениеФайловИзИнтернета") Тогда
		МодульПолучениеФайловИзИнтернета = ОбщегоНазначения.ОбщийМодуль("ПолучениеФайловИзИнтернета");
		Протокол = ?(ЗащищенноеСоединение = Неопределено, "ftp", "ftps");
		Прокси = МодульПолучениеФайловИзИнтернета.ПолучитьПрокси(Протокол);
	КонецЕсли;
	
	Возврат Прокси;
	
КонецФункции
Показать
12. Docaru 1 10.12.20 20:47 Сейчас в теме
(10)у фреша при добавлении расширения есть даже специальное "разрешение"
Прикрепленные файлы:
13. user1503726 10.12.20 20:53 Сейчас в теме
(12) красота конечно страшная сила, а порт 21 это куда то надо указывать?
14. Docaru 1 10.12.20 20:56 Сейчас в теме
(13)пор 21 по умолчанию есть в
Функция FTPНастройкиСоединения(Знач Таймаут = 180) Экспорт
	
	Результат = Новый Структура;
	Результат.Вставить("Сервер", "");
	Результат.Вставить("Порт", 21);
	Результат.Вставить("ИмяПользователя", "");
	Результат.Вставить("ПарольПользователя", "");
	Результат.Вставить("ПассивноеСоединение", Ложь);
	Результат.Вставить("Таймаут", Таймаут);
	Результат.Вставить("ЗащищенноеСоединение", Неопределено);
	
	Возврат Результат;
КонецФункции
Показать
15. user1503726 10.12.20 21:04 Сейчас в теме
А где именно файл не обнаружен? Здесь или там?
16. Docaru 1 10.12.20 21:07 Сейчас в теме
(15)
))) "тута"
а если серьезно - все происходит в одной функции на сервере: сперва файл создается, заполняется и ТУТ же отправляется на фтп.
17. Docaru 1 10.12.20 21:10 Сейчас в теме
поверьте - я прошел долгий путь с этой выгрузкой. Указывал имяфайла, потом через временное хранилище, последним уже было поток памяти. Сейчас временно сделал заплатку - клиент сам будет сохранять файл локально и ручаками копировать на фтп - жду когда пройдет аудит, чтобы "обрадовать" клиента. Но коллеги! Это ж бред! в БСП уже есть штатная возможность отправялть отчеты на фтп/почту/папку. НО там нет моего "любимого" dbf...
18. user1503726 10.12.20 21:12 Сейчас в теме
Верю. Может сменить ему расширение, чтоб приняли за "своего" в БСП?
19. Docaru 1 10.12.20 21:14 Сейчас в теме
(18)и это было (((
удалял и загружал по-новой. Складывается ощущение, что вся проблема именно во Фреше... Надеюсь есть здесь поддержка фреша - что то подскажут
20. uno-c 238 10.12.20 21:19 Сейчас в теме
Возможно, у Вас нет прав создавать временный каталог. Попробуйте обойтись без него - он в общем-то и не нужен ради одного файла. Сделайте просто ИмяФайла = ПолучитьИмяВременногоФайла("dbf")
21. Docaru 1 10.12.20 21:21 Сейчас в теме
(20)во-первых права есть-смотри принтскрин, во вторых я так и думал, что моя строка
КаталогВФ = ФайловаяСистема.СоздатьВременныйКаталог();
ИмяФайла = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку("%1Price.dbf",КаталогВФ);
кому-нибудь бросится в глаза. Открою секрет - если вы так
ИмяФайла = ПолучитьИмяВременногоФайла("dbf")
попробуете создать файл xbase, получите ошибку "Длина имени файла не может быть больше 8 символов".
)))
Прикрепленные файлы:
user1503726; +1 Ответить
23. uno-c 238 10.12.20 21:27 Сейчас в теме
(21)Ну тогда ИмяФайла = КаталогВременныхФайлов() + "Price.dbf". Чтобы отмести вариант когда файлы во временном каталоге можно создавать, а подкаталоги нельзя.
24. Docaru 1 10.12.20 21:31 Сейчас в теме
(23)есть риск, что файл "Price.dbf" уже есть -во Фреше тысячи баз...
и была такая ошибка, когда во Фреше специалисты не правильно загрузили расширение - файл действительно не создвался и была соответствующая ошибка. Сейчас этой ошибки нет, значит файл создается. Надеюсь завтра аудит пройдет и если я смогу сохраниться файл локально, значит проблем с временными папками нет точно
28. uno-c 238 10.12.20 21:35 Сейчас в теме
(24)Вы таки попробуйте без подкаталога - мало ли что там у линукса настроено. Если пройдет - потом можно будет подумать как имя файла случайное восьмисимвольное сделать - тем более что это несложно - обрезать предложенное ПолучитьИмяВременногоФайла
30. Docaru 1 10.12.20 21:36 Сейчас в теме
(28)
думаю завтра будет точно известно - если файл локально сохраню, то с временными папками и имененм все ок.
22. user1503726 10.12.20 21:25 Сейчас в теме
Тогда зачем временное хранилище здесь до отправки данных ?
И что такое имядляпрайса?
25. uno-c 238 10.12.20 21:32 Сейчас в теме
(22)Оно вообще здесь не нужно. Смысл помещать в хранилище строковый примитив, а потом эту строку оттуда доставать )))
27. Docaru 1 10.12.20 21:34 Сейчас в теме
(25)во-первых адрес ВХ мне нужно, чтобы клиент смог выгрузить файл локально, во вторых я уже говорил, что
FTPСоединение.Записать(ИмяФайла, ПутьДляПрайса + "Price.dbf");
приводит к той же ошибке - файл не найден.
повторюсь - я уже 3 вариант перепробовал...
29. uno-c 238 10.12.20 21:36 Сейчас в теме
(27)Строковую переменную не нужно помещать во временное хранилище - ее клиенту можно так же передать, как и сам адресВоВременномХранилище.
26. Docaru 1 10.12.20 21:32 Сейчас в теме
(22)я сохраняю адрес ВХ чтобы потом клиент локально мог файл сохранить
33. Docaru 1 10.12.20 21:46 Сейчас в теме
(22)вы наверно имели в виду "ПутьДляПрайса" - это реквизит - указывается папка на фтп, куда сохраняется этот файл.
31. user1503726 10.12.20 21:40 Сейчас в теме
Случайно, не реквизит фиксированной длины для имени файла, конечные пробелы не мешают ?
32. Docaru 1 10.12.20 21:41 Сейчас в теме
(29)что вы предлагаете записать во временное хранилище, чтобы потом передать на клиент?
(31)не понял - можете пояснить?
34. uno-c 238 10.12.20 21:46 Сейчас в теме
(32)Я ничего не предлагаю - это за рамками темы. Строку обычно напрямую между клиентом и сервером передают, если это не фоновое задание. И клиент точно у Вас с этим адресом файла уже ничего не сделает если ФТП без ошибки пройдет - у Вас же строчка ФайловаяСистема.УдалитьВременныйКаталог(КаталогВФ);
36. Docaru 1 10.12.20 21:49 Сейчас в теме
(34)как раз для этого и придуман метод ПоместитьВоВременноеХранилище / ПолучитьИзВременногоХранилища. между клиентом и сервером передается адрес ВХ. клиент может спокойно его себе загрузить. ИмяФайла не совсем просто строка: после операции ФайлПрайс.СоздатьФайл(ИмяФайла); это уже данные.
37. uno-c 238 10.12.20 21:50 Сейчас в теме
(36)Да ладно. ИмяФайла - это как была строка так и осталась.
39. user1503726 10.12.20 21:50 Сейчас в теме
40. uno-c 238 10.12.20 21:51 Сейчас в теме
41. Docaru 1 10.12.20 21:51 Сейчас в теме
(37)не хочу спорить, но именно так у меня получается на клиенте сохранить файл, созданный на сервере.
42. uno-c 238 10.12.20 21:51 Сейчас в теме
(41)Видимо комп один и тот же
35. user1503726 10.12.20 21:49 Сейчас в теме
Возможно сокрлп(путьдляфайла) будет более правильно, в порядке танцев с бубном?
38. Docaru 1 10.12.20 21:50 Сейчас в теме
(35)а еще идеи будут? )))
шучу - не обижайтесь. Я уже готов на любой бубен
43. Docaru 1 10.12.20 21:54 Сейчас в теме
сейчас на аудите вариант
FTPСоединение.Записать(ИмяФайла, ПутьДляПрайса + "Price.dbf");
ждем заватра
user1503726; +1 Ответить
44. user1503726 10.12.20 21:59 Сейчас в теме
Если платформа в основном гибко относится к передаваемым параметрам и понимает и файл и имя файла, скорее всего не означает что после использования методов 1с все остальные могут столь же свободно этим пользоваться.
45. uno-c 238 10.12.20 22:06 Сейчас в теме
А не переводит ли в нижний регистр "Price.dbf" при сохранении? Раз он такой капризный к 8 символам ... На винде это некритично, но на линуксе это разные имена Price и price - можно даже рядом два файла положить "Price.dbf" и "price.dbf"и проблем не будет - это разные файлы с точки зрения линукса.
46. uno-c 238 10.12.20 22:12 Сейчас в теме
Проверил. Получилось почти как я говорил. При записи dbf-ки расширение делается DBF - заглавными буквами (хотя просили маленькими) В этом проблема. Потом код ищет файл "Price.dbf", но там реально лежит уже "Price.DBF" - и для линукса это другой файл, в отличие от винды.
user1503726; +1 Ответить
47. uno-c 238 10.12.20 22:14 Сейчас в теме
А то что на фреше линукс - видно из Файл не обнаружен '/temp/v8_fCb9XW_1/Price.dbf' - слеши в другую сторону и корень с "/" начинается, а не с имени диска.
user1503726; +1 Ответить
48. uno-c 238 10.12.20 22:25 Сейчас в теме +10 $m
В общем, мои рекомендации - сделать
ИмяФайла = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку("%1PRICE.DBF",КаталогВФ);
- т.е. "PRICE.DBF" - полностью верхний регистр. Если xbase помнит старинные правила 8.3 - то там и регистр только верхний когда-то был )
support; Docaru; unknow_user; user1503726; +4 Ответить
49. Docaru 1 10.12.20 23:03 Сейчас в теме
(48)ок. отправляю на аудит так. если честно, то это больше похоже на правду.
PS с временным хранилищем - мой косяк, признаюсь - сохранял путь, а не двоичные данные. а с этим во фреше свои ограничения...
53. Docaru 1 11.12.20 12:20 Сейчас в теме
(48)два чая этому господину!
Дружище! Иди обниму! все так и есть - имя нужно укзаывать большими буквами.
support; uno-c; +2 Ответить
54. uno-c 238 11.12.20 13:23 Сейчас в теме
(53) Рад, что мы прошли этот квест, жму крепко руку!
50. Tiger77 69 11.12.20 04:07 Сейчас в теме
Рабочий код:


&НаСервере
Функция  ВыгрузитьПрайсНаСервере()
    ИмяФайла = ПолучитьИмяВременногоФайла(".dbf");
   
    ФайлПрайс = Новый XBase;
    ФайлПрайс.Кодировка = КодировкаXBase.OEM;
    ФайлПрайс.поля.Добавить("CODEPST","S",36,0);
    ФайлПрайс.поля.Добавить("NAME","S",200,0);
    ФайлПрайс.поля.Добавить("CNTR","S",100,0);
    ФайлПрайс.поля.Добавить("FIRM","S",150,0);
    ФайлПрайс.поля.Добавить("QNTPACK","N",10,0);
    ФайлПрайс.поля.Добавить("EAN13","S",13,0);
    ФайлПрайс.поля.Добавить("GDATE","D",8,0);
    ФайлПрайс.поля.Добавить("QNT","N",8,0);
    ФайлПрайс.поля.Добавить("PRICE","N",10,2);
    ФайлПрайс.поля.Добавить("RATEPACK","N",10,0);
    ФайлПрайс.СоздатьФайл(ИмяФайла);
    ФайлПрайс.Записать();
    Для каждого Строка Из ТЗПрайс Цикл
        
        ФайлПрайс.Добавить();
        ЗаполнитьЗначенияСвойств(ФайлПрайс,Строка);    
        Если Не Строка.ЦенаВключаетНДС Тогда
            СтавкаНДС = СтавкаНДСНаСервере(Строка.ВидСтавкиНДС);
            ЗначениеСтавкиНДС = УчетНДСВызовСервераПовтИсп.ПолучитьСтавкуНДС(СтавкаНДС, Ложь);
            ФайлПрайс.PRICE   = Строка.PRICE * (1 + ЗначениеСтавкиНДС / 100);
        КонецЕсли;
        ФайлПрайс.Записать();
    КонецЦикла; 
    ФайлПрайс.ЗакрытьФайл();

    Попытка
        FTPСоединение = ПолучитьFTPСоединение();
    Исключение
        ТекстОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
        ПолучитьСообщениеОбОшибке(102);
        ДополнитьСообщениеОбОшибке(ТекстОшибки);
        Возврат Ложь;
        
    КонецПопытки;
    
    Попытка

	FTPСоединение.Записать(ИмяФайла, ПутьДляПрайса + "Price.dbf");
    Исключение
        ТекстОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
        ПолучитьСообщениеОбОшибке(103);
        ДополнитьСообщениеОбОшибке(ТекстОшибки);
        Возврат Ложь;
    КонецПопытки;
    
    Попытка
        МассивФайлов = FTPСоединение.НайтиФайлы(ПутьДляПрайса, "Price.dbf", Ложь);
    Исключение
        ТекстОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
        ПолучитьСообщениеОбОшибке(104);
        ДополнитьСообщениеОбОшибке(ТекстОшибки);
        Возврат Ложь;
    КонецПопытки;
	УдалитьФайл(ТмяФайла);
    Возврат МассивФайлов.Количество() > 0;
КонецФункции


Показать
unknow_user; +1 Ответить
51. uno-c 238 11.12.20 07:10 Сейчас в теме
(50)
Рабочий код

Не работает даже на 2008R2 + 8.3.17.1496 Серверный
52. Docaru 1 11.12.20 09:01 Сейчас в теме
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот