Имя: Пароль:
1C
1С v8
Как убрать неразрывный пробел в числах непосредственно в запросе?
0 DenYuliya
 
06.07.23
22:28
Всем добрый день.
Вопрос:реально ли убрать каким-нибудь относительно коротким, а не порнографическим, как например тут https://ta2i4.ru/float-to-string , методом, убрать неразрывные пробелы в числах напрямую в запросе? Пример: было 1 000, должно стать 1000. Заказчик прям хочет, мешают ему неразрывные пробелы в csv.

Есть адский запрос, там порядка 35 временных таблиц, везде сплошные цифры, расчеты и итоги, "счетчик" строк по вложенным группировкам (через Автономерзаписи()) и лютый лютый треш.
Все это хозяйство прямо из Результата запроса выгружается в ТЗ, потом в текстовый документ, а оттуда - в файл csv.
То есть вне запроса результат не обрабатывается, никаких циклов и вообще ничего. Мне кажется, что это хозяйство построчно перебирать -с ума сойдешь.

ИЗ ТЗ (результат запроса) CSV выгружается так:

&НаКлиенте
Процедура ВыгрузитьДвижения(Команда)
    
    ТекстДок = ВыгрузитьДвиженияНаСервере(); ///тут результат запроса
    ИмяФайлаДвижения = ПолучитьИмяФайлаДвижения();  
    ИмяФайла = СокрЛП(ИмяФайлаДвижения);
        ВыгрузитьТекстовыйДокументВФайл(ТекстДок, ИмяФайла);
    
    //ТекстДок.Показать();  ///это можно потом убрать         
    
КонецПроцедуры

&НаСервере
Функция ВыгрузитьДвиженияНаСервере()
    
    ДатаСобытия = Формат(Объект.Период.ДатаОкончания, "ДЛФ=Д");
    ТЗ_ДанныеДвижения = ДанныеДвиженияВПериоде(ДатаСобытия); ///тут прилетает ТЗ с результатом запроса. Все, больше с результатом запроса не делается ничего и никак.
            
    СимволРазделителя = ",";
    КодANSI = КодировкаТекста.ANSI;
    ТекстCSV = СоздатьДанныеCSV(ТЗ_ДанныеДвижения, СимволРазделителя);
    ТекстДокДвижения = Новый ТекстовыйДокумент;  
    ТекстДокДвижения.УстановитьТипФайла(КодANSI);
    ТекстДокДвижения.УстановитьТекст(ТекстCSV);
    
    Возврат ТекстДокДвижения;  
    
КонецФункции

/////сохранение в CSV    
&НаКлиенте              
Процедура ВыгрузитьТекстовыйДокументВФайл(ТекстовыйДокумент, ИмяФайла) Экспорт

    // Формируем для передачи данных между процедурами  
    нИмяФайла = СокрЛП(ИмяФайла) + ".csv";
    ПараметрыТекстовогоДокумента = Новый Структура("ТекстовыйДокумент , ИмяФайла", ТекстовыйДокумент, нИмяФайла);
    
    #Если ВебКлиент Тогда
        
        ОповещениеПодключенияРасширения = Новый ОписаниеОповещения(
            "ЗавершитьПодключениеРасширенияРаботыСФайлами_csv", ЭтаФорма, ПараметрыТекстовогоДокумента);             
            НачатьПодключениеРасширенияРаботыСФайлами(ОповещениеПодключенияРасширения);
        Возврат;
        
    #КонецЕсли
    
    СохранениеТекстовогоДокументаВФайл(ТекстовыйДокумент, нИмяФайла);

КонецПроцедуры // ВыгрузитьТекстовыйДокументВФайл()

&НаКлиенте
Процедура ЗавершитьПодключениеРасширенияРаботыСФайлами_csv(Подключено, ДополнительныеПараметры) Экспорт

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

КонецПроцедуры // ЗавершитьПодключениеРасширенияРаботыСФайлами()

&НаКлиенте
Процедура СохранениеТекстовогоДокументаВФайл(ТекстовыйДокумент, нИмяФайла)  
    
    АдресХранилища = ПоместитьТекстовыйДокументВоВременноеХранилищеНаСервере(ТекстовыйДокумент, ".csv"); // ТипФайлаТабличногоДокумента.TXT);
    
    Если АдресХранилища = Неопределено Тогда
        ПоказатьПредупреждение( , "При сохранение файла возникла ошибка");
        Возврат;
    КонецЕсли;
        
    Попытка
        ПолучитьФайл(АдресХранилища, нИмяФайла, Истина);
    Исключение                
        Сообщение = Новый СообщениеПользователю;
        Сообщение.Текст = "Не удалось записать файл. Возможно, недостаточно места на диске, диск защищен от записи или не подключено расширение для работы с файлами.";
        Сообщение.Сообщить();
    КонецПопытки;

КонецПроцедуры // СохранениеТекстовогоДокументаВФайл()

&НаСервере
Функция ПоместитьТекстовыйДокументВоВременноеХранилищеНаСервере(ТекстовыйДокумент, Расширение) Экспорт
    
    АдресХранилища    = Неопределено;
    ИмяФайла        = ПолучитьИмяВременногоФайла(Расширение);
    
    Попытка
        ТекстовыйДокумент.Записать(ИмяФайла);
        АдресХранилища = ПоместитьВоВременноеХранилище(Новый ДвоичныеДанные(ИмяФайла));
    Исключение
        ВызватьИсключение;
    КонецПопытки;
    
    Возврат АдресХранилища;
    
КонецФункции // ПоместитьТекстовыйДокументВоВременноеХранилищеНаСервере()

&НаСервере
Процедура ВыгрузкаВФайлCSV(ТЗ, ИмяФайла) //Выгрузка в файл CSV и его создание в 1С
    СимволРазделителя = ",";
    ТекстCSV = СоздатьДанныеCSV(ТЗ, СимволРазделителя);
    ТекстовыйДокумент = Новый ТекстовыйДокумент;
    ТекстовыйДокумент.УстановитьТекст(ТекстCSV);     
КонецПроцедуры    

// Создаем строку загоовков для CSV-файла
&НаСервере
Функция СоздатьЗаголовкиCSV(ТЗ, СимволРазделителя)
    
    КолонкиТЗ = ТЗ.Колонки;
    стрКолонки = "";
    
    Для каждого Колонка Из КолонкиТЗ Цикл      
        Если СтрДлина(стрКолонки)>0 Тогда
            стрКолонки = стрКолонки + СимволРазделителя;
        КонецЕсли;    
        
        стрКолонки = стрКолонки + колонка.Имя;      
    КонецЦикла;
    
    Возврат стрКолонки;
    
КонецФункции

// Создаем строку записи ТаблицыЗначений для CSV-файла
&НаСервере
Функция СоздатьСтрокуCSV(ЗаписьТЗ, СимволРазделителя)    
    
    стрЗапись = "";    
    
    Для каждого Поле Из ЗаписьТЗ Цикл
        
        Если СтрДлина(стрЗапись) > 0 Тогда
            стрЗапись = стрЗапись + СимволРазделителя;
        КонецЕсли;    
        
        Если ТипЗнч(поле) = Тип("Число") Тогда
            стрПоле = ?(ЗначениеЗаполнено(поле),Формат(поле,"ЧРД=."),"0");        
        ИначеЕсли ТипЗнч(поле) = Тип("Дата") Тогда
            стрПоле = Формат(поле,"ДФ=dd.MM.yyyy");          
        Иначе //Если ТипЗнч(поле) = Тип("Строка") Тогда          
            стрПоле = СтрЗаменить(Строка(поле),"""","""""");        
            Если
                ( СтрНайти(стрПоле," ") > 0  ) ИЛИ
                  ( СтрНайти(стрПоле,"""") > 0 ) ИЛИ
                  ( СтрНайти(стрПоле,",") > 0  ) ИЛИ
                  ( СтрНайти(стрПоле,";") > 0  ) ИЛИ
                  ( СтрНайти(стрПоле,Символы.Таб) > 0 )  ИЛИ
                  ( СтрНайти(стрПоле,Символы.ВК) > 0 )   ИЛИ
                  ( СтрНайти(стрПоле,Символы.ПФ) > 0 )   ИЛИ
                  ( СтрНайти(стрПоле,Символы.ВТаб) > 0 ) ИЛИ
                  ( СтрНайти(стрПоле,Символы.НПП) > 0 )  ИЛИ
                  ( СтрНайти(стрПоле,Символы.ПС) > 0 )
            Тогда
                стрПоле = """" + стрПоле + """";
            КонецЕсли;                
        КонецЕсли;    
        
        стрЗапись = стрЗапись + Строка(стрПоле);
        
    КонецЦикла;
    
    Возврат стрЗапись;
    
КонецФункции

&НаСервере
Функция СоздатьДанныеCSV(ТЗ, СимволРазделителя = ",")
    
    ТекстCSV = "";  
    
    Если ВыводитьЗаголовки Тогда
        ТекстCSV = СоздатьЗаголовкиCSV(ТЗ, СимволРазделителя);    
    КонецЕсли;
    
    Для Каждого Стр Из ТЗ Цикл      
        стрЗапись = СоздатьСтрокуCSV(Стр ,СимволРазделителя);            
        Если СтрДлина(стрЗапись) > 0 Тогда
            ТекстCSV = ТекстCSV + Символы.ПС;
        КонецЕсли;
        ТекстCSV = ТекстCSV + стрЗапись;        
    КонецЦикла;        

    Возврат ТекстCSV;

КонецФункции // СоздатьДанныеCSV()
1 vde69
 
06.07.23
22:34
не разрывные пробелы бывают только в ТЕКСТЕ, в ЧИСЛАХ их не может быть
2 DenYuliya
 
06.07.23
22:38
(1) да пофигу, как это называется). Когда число отображается 1 000, а не 1000
3 Мимохожий Однако
 
06.07.23
22:43
формат без группировки и разделителей
4 DenYuliya
 
06.07.23
22:47
(3) в запросе ведь нет функции ФОРМАТ()? И там числа ведь, а не строки. Если даже теоретически преобразовать каждое число - строку - как тогда итоговые расчеты производить? Мне же не только итоги надо преобразовать, а каждую из строк результата.
5 Мимохожий Однако
 
06.07.23
22:51
нет смысла преобразовывать в запросе. Достаточно постобработки
6 Мультук
 
06.07.23
22:56
(4)

А это что ?

Если ТипЗнч(поле) = Тип("Число") Тогда
            стрПоле = ?(ЗначениеЗаполнено(поле),Формат(поле,"ЧРД=."),"0");    


===

Если ТипЗнч(поле) = Тип("Число") Тогда
            стрПоле = ?(ЗначениеЗаполнено(поле),Формат(поле,"ЧРД=.; ЧГ="),"0");
7 DenYuliya
 
06.07.23
23:13
(6) а хз, дернуто из работающего общего модуля. Фактически все, кроме запроса. Работает, и хвала богам. Там еще момент есть, что клиент работает не на сервере, а в веб версии.
8 DenYuliya
 
06.07.23
23:14
(5) так в том и вопрос, как это сделать В ЗАПРОСЕ. Потому как делать постобработку этого запроса будет безумно трудоемко.
9 PR
 
06.07.23
23:18
(8) А пациент упоротенький, я смотрю, хочет вот он и все тут
Тебе же уже сказали, что в запросе менять не нужно
Хотя и можно в новых платформах
Если уж так хочется избавиться от неразрывных пробелов, удали потом в csv одной строчкой все неразрывные пробелы
10 DenYuliya
 
06.07.23
23:28
(9) Каким образом можно удалить из csv?
11 timurhv
 
06.07.23
23:59
(0) Результат запроса в 1С от региональных настроек сервера SQL может и не 1 000 вернуть, а 1.000 или 1,000.
12 timurhv
 
07.07.23
00:06
(8) Очень сомнительно, учитывая конструкции вида
            Если
                ( СтрНайти(стрПоле," ") > 0  ) ИЛИ
                  ( СтрНайти(стрПоле,"""") > 0 ) ИЛИ
                  ( СтрНайти(стрПоле,",") > 0  ) ИЛИ
                  ( СтрНайти(стрПоле,";") > 0  ) ИЛИ
                  ( СтрНайти(стрПоле,Символы.Таб) > 0 )  ИЛИ
                  ( СтрНайти(стрПоле,Символы.ВК) > 0 )   ИЛИ
                  ( СтрНайти(стрПоле,Символы.ПФ) > 0 )   ИЛИ
                  ( СтрНайти(стрПоле,Символы.ВТаб) > 0 ) ИЛИ
                  ( СтрНайти(стрПоле,Символы.НПП) > 0 )  ИЛИ
                  ( СтрНайти(стрПоле,Символы.ПС) > 0 )
13 Mort
 
07.07.23
00:08
В (6)  ответили. В функции сбора CSV добавить в формат() "ЧГ="
14 PR
 
07.07.23
00:17
(10) СтрЗаменить
15 DenYuliya
 
07.07.23
00:23
(11) блин, так "от региональные настройки" - это для всего сервера, а не для отдельной базы(((? Тогда отпадает вариант. Я думала, можно установить их для одной отдельной базы из многих на сервере, но еще не пробовала этот вариант.
16 DenYuliya
 
07.07.23
00:26
(14) это не в запросе ведь. + там не строки, а числа.  Если даже теоретически преобразовать каждое число - строку - как тогда итоговые расчеты производить? Мне же не только итоги надо преобразовать, а каждую из строк результата.

(13) о божечки-кошечки, я не так поняла ответ. Вот что значит бездумное копирование чужого кода. Я попробую так, спасибо! и (6) спасибо за совет!
17 DenYuliya
 
07.07.23
00:29
(12) ну это да... вот и я только такие примеры нашла. В 35  временных запросов, в которых большая часть значений полей - это числа, только такой колбасы не хватает. + есть у меня сомнения (не проверяла), что после преобразования промежуточных числовых значений в строковые - корректно "пойдут" дальнейшие вычисления.
Я-то надеялась, что мне щас какой-нибудь универсальный синтаксис подскажут, что-нибудь типа Автономерзаписи() (я имею в виду по краткости написания).
18 DenYuliya
 
07.07.23
10:57
(6) спасибо большое, это то, что надо!
19 lEvGl
 
07.07.23
12:51
гляжу в книгу
Оптимист верит, что мы живем в лучшем из миров. Пессимист боится, что так оно и есть.