Имя: Пароль:
1C
1С v8
Слова Рус/Лат
0 Mikhail Volkov
 
28.04.17
16:01
Как-то в УАТ сталкивался с задаче исправлять в гос. номерах автотранспорта латинские буквы на русские. Например, есть лат. символы по написанию очень  похожие на рус.: C, T,  P, Y, X и т.д. Там просто заменой исправлялось. Теперь задача посложнее: в наименованиях , артикулах, описаниях номенклатуры могут встречаться "слова" (отделенные от остальных символов пробелами или спец. символами: - / \ ( ) [ ] , ;...) лат. символов, но тогда они все должны быть лат. Например, есть S, V, Z, W - никак не похожих на русские, и в слове русские похожие на лат. Тогда все буквы этого слова нужно исправить на лат. И наоборот.
Не типичная для 1С задача (больше для веб-сайтов), но может известны готовые решения для 1С?
1 Naf2017
 
28.04.17
16:07
дарю

Функция ЛатинскийАртикул(Артикул) Экспорт
    
    Алфавит = "ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮЁ";
    РусскиеАналоги="АВЕКМНОРСТХ";
    ЛатинскАналоги="ABEKMHOPCTX";
    НовыйАртикул = "";        
    РусскиеБуквыЕсть = Ложь;
    ПлохиеБуквыЕсть = Ложь;
    Для й=1 По СтрДлина(Артикул) Цикл
        Буква = Сред(Артикул,й,1);
        Если Найти(Алфавит,Буква)>0 Тогда
            РусскиеБуквыЕсть = Истина;
            ИндексАналога = Найти(РусскиеАналоги,Буква);
            Если ИндексАналога=0 Тогда
                ПлохиеБуквыЕсть = Истина;
                Прервать;
            КонецЕсли;
            НовыйАртикул = НовыйАртикул + Сред(ЛатинскАналоги,ИндексАналога,1);
        Иначе
            НовыйАртикул = НовыйАртикул + Буква;
        КонецЕсли;
    КонецЦикла;
    
    Если ПлохиеБуквыЕсть Тогда
        Возврат Артикул;
    Иначе
        Возврат НовыйАртикул;
    КонецЕсли;
    
    
КонецФункции
2 Fragster
 
гуру
28.04.17
16:22
требую комментария к             ИндексАналога = Найти(РусскиеАналоги,Буква);
            Если ИндексАналога=0 Тогда
                ПлохиеБуквыЕсть = Истина;
3 Mikhail Volkov
 
28.04.17
17:23
(1) Эта функция заменяет символы из РусскиеАналоги на символы из ЛатинскАналоги. В итоге возвращает слово только из лат. символов. Кстати, У с Y тоже путают.
Мне вначале надо определятся Рус. или Лат. слово по ПлохиеБуквы. Но идея понятна. Спс.
(2) ПлохиеБуквы - это НЕ РусскиеАналоги из Алфавит
4 Fragster
 
гуру
28.04.17
18:03
0 - это же "не нашли"
5 Mikhail Volkov
 
28.04.17
18:48
(4) "не нашли" среди РусскиеАналоги - "плохая" буква, не спутать с Лат.
6 Fragster
 
гуру
28.04.17
18:54
понятно. без комментариев сложно.
7 Mikhail Volkov
 
29.04.17
08:35
(1) Идея понравилась:

// Русские буквы без аналогов латинских
//
Функция РусБуквы() Экспорт
    Возврат "ЙЦГШЩЗЪФЫПЛДЖЭЯЧИЬБЮ";
КонецФункции

// Русские буквы аналоги латинских
//
Функция РусАналоги() Экспорт
    Возврат "АВЕКМНОРСТХУ";
КонецФункции

// Латинские буквы без аналогов русских
//
Функция ЛатБуквы() Экспорт
    Возврат "QWRUISDFGJLZVN";
КонецФункции

// Латинские буквы аналоги русских
//
Функция ЛатАналоги() Экспорт
    Возврат "ABEKMHOPCTXY";
КонецФункции

Функция ВсеБуквы() Экспорт
    Возврат РусБуквы() + РусАналоги() + ЛатБуквы() + ЛатАналоги();
КонецФункции

// Осуществляет поиск первого слова с комбинацией рус./лат. букв
// РусЛатСлово - найденное первое слово
// ИсправленноеСлово - сформированное исправленное слово, если исправление возможно
// Возвращает Истина для найденного РусЛатСлово
Функция НайтиРусЛатСлово(Строка, РусЛатСлово = "", ИсправленноеСлово = "") Экспорт
    ЕстьРусБуквы = Ложь; ЕстьРусАналоги = Ложь; ЕстьЛатБуквы = Ложь; ЕстьЛатАналоги = Ложь;
    Для СчетчикСимволов = 1 По СтрДлина(Строка) Цикл
        Символ = Сред(Строка, СчетчикСимволов, 1);
        ПредыдущийСимвол = Прав(РусЛатСлово, 1);
        Если (Найти(ВсеБуквы(), ВРег(ПредыдущийСимвол)) = 0) = (Найти(ВсеБуквы(), ВРег(Символ)) = 0) Тогда
            РусЛатСлово = РусЛатСлово + Символ;
        Иначе // конец РусЛатСлово
            Если Не ПустаяСтрока(РусЛатСлово) Тогда
                Если ЕстьРусБуквы И ЕстьЛатБуквы Тогда
                    Возврат Истина; // Неисправляемая комбинация рус./лат. букв
                ИначеЕсли ЕстьРусБуквы И ЕстьЛатАналоги Тогда
                    ИсправленноеСлово = ИсправленноеРусЛатСлово(РусЛатСлово, Истина);
                    Возврат Истина; // Исправленное на русское
                ИначеЕсли ЕстьЛатБуквы И ЕстьРусАналоги Тогда
                    ИсправленноеСлово = ИсправленноеРусЛатСлово(РусЛатСлово, Ложь);
                    Возврат Истина; // Исправленное на латинское
                КонецЕсли;
                РусЛатСлово = "";
             КонецЕсли;
            ЕстьРусБуквы = Ложь; ЕстьРусАналоги = Ложь; ЕстьЛатБуквы = Ложь; ЕстьЛатАналоги = Ложь;
        КонецЕсли;
    КонецЦикла;
    Возврат Ложь;
КонецФункции

// Исправляет комбинацию рус./лат. букв строки на русскую,
// при РусЛатИсправление = Истина, или наоборот - латинскую
Функция ИсправленноеРусЛатСлово(Строка, РусЛатИсправление) Экспорт
    ИсправленноеСлово = "";
    Для СчетчикСимволов = 1 По СтрДлина(Строка) Цикл
        Символ = Сред(Строка, СчетчикСимволов, 1);
        ИндексАналога = Найти(?(РусЛатИсправление, ЛатАналоги(), РусАналоги()), Символ);
        ИсправленноеСлово = ИсправленноеСлово + ?(ИндексАналога = 0, Символ, Сред(?(РусЛатИсправление, РусАналоги(), ЛатАналоги()), ИндексАналога, 1));
    КонецЦикла;
    Возврат ИсправленноеСлово;
КонецФункции

Пока не проверял...
8 Mikhail Volkov
 
01.05.17
05:07
Исправил:

// Осуществляет поиск первого слова с комбинацией рус./лат. букв
// РусЛатСлово - найденное первое слово
// ИсправленноеСлово - сформированное исправленное слово, если исправление возможно
// Возвращает Истина для найденного РусЛатСлово
Функция НайтиРусЛатСлово(Строка, РусЛатСлово = "", ИсправленноеСлово = "") Экспорт
    ЕстьРусБуквы = Ложь; ЕстьРусАналоги = Ложь; ЕстьЛатБуквы = Ложь; ЕстьЛатАналоги = Ложь;
    Для СчетчикСимволов = 1 По СтрДлина(Строка) Цикл
        Символ = Сред(Строка, СчетчикСимволов, 1);
        ПредыдущийСимвол = Прав(РусЛатСлово, 1);
        Если (Найти(ВсеБуквы(), ВРег(ПредыдущийСимвол)) = 0) = (Найти(ВсеБуквы(), ВРег(Символ)) = 0) Тогда
            РусЛатСлово = РусЛатСлово + Символ;
            ЕстьРусБуквы   = ЕстьРусБуквы Или Не(Найти(РусБуквы(), ВРег(Символ)) = 0);
            ЕстьРусАналоги = ЕстьРусАналоги Или Не(Найти(РусАналоги(), ВРег(Символ)) = 0);
            ЕстьЛатБуквы   = ЕстьЛатБуквы Или Не(Найти(ЛатБуквы(), ВРег(Символ)) = 0);
            ЕстьЛатАналоги = ЕстьЛатАналоги Или Не(Найти(ЛатАналоги(), ВРег(Символ)) = 0);
        Иначе // конец РусЛатСлово
            Если Не ПустаяСтрока(РусЛатСлово) Тогда
                Если ЕстьРусБуквы И ЕстьЛатБуквы Тогда
                    Возврат Истина; // Неисправляемая комбинация рус./лат. букв
                ИначеЕсли ЕстьРусБуквы И ЕстьЛатАналоги Тогда
                    ИсправленноеСлово = ИсправленноеРусЛатСлово(РусЛатСлово, Истина);
                    Возврат Истина; // Исправленное на русское
                ИначеЕсли ЕстьЛатБуквы И ЕстьРусАналоги Тогда
                    ИсправленноеСлово = ИсправленноеРусЛатСлово(РусЛатСлово, Ложь);
                    Возврат Истина; // Исправленное на латинское
                КонецЕсли;
                РусЛатСлово = "";
             КонецЕсли;
            ЕстьРусБуквы = Ложь; ЕстьРусАналоги = Ложь; ЕстьЛатБуквы = Ложь; ЕстьЛатАналоги = Ложь;
        КонецЕсли;
    КонецЦикла;
    Возврат Ложь;
КонецФункции

// Исправляет комбинацию рус./лат. букв строки на русскую,
// при РусЛатИсправление = Истина, или наоборот - латинскую
Функция ИсправленноеРусЛатСлово(Строка, РусЛатИсправление) Экспорт
    ИсправленноеСлово = "";
    Для СчетчикСимволов = 1 По СтрДлина(Строка) Цикл
        Символ = Сред(Строка, СчетчикСимволов, 1);
        ИндексАналога = Найти(?(РусЛатИсправление, ЛатАналоги(), РусАналоги()), ВРег(Символ));
        ИсправленноеСлово = ИсправленноеСлово + ?(ИндексАналога = 0, Символ, ?(Символ = ВРег(Символ),
                            Сред(?(РусЛатИсправление, РусАналоги(), ЛатАналоги()), ИндексАналога, 1),
                       НРег(Сред(?(РусЛатИсправление, РусАналоги(), ЛатАналоги()), ИндексАналога, 1))));
    КонецЦикла;
    Возврат ИсправленноеСлово;
КонецФункции
9 Mikhail Volkov
 
07.05.17
07:40
Еще исправил:

Функция НайтиРусЛатСлово(Строка, РусЛатСлово = "", ИсправленноеСлово = "") Экспорт
    ЕстьРусБуквы = Ложь; ЕстьРусАналоги = Ложь; ЕстьЛатБуквы = Ложь; ЕстьЛатАналоги = Ложь;
    Для СчетчикСимволов = 1 По СтрДлина(Строка) Цикл
        Символ = Сред(Строка, СчетчикСимволов, 1);
        ПредыдущийСимвол = Прав(РусЛатСлово, 1);
        Если (Найти(ВсеБуквы(), ВРег(ПредыдущийСимвол)) = 0) = (Найти(ВсеБуквы(), ВРег(Символ)) = 0) Тогда
            РусЛатСлово = РусЛатСлово + Символ;
            ЕстьРусБуквы   = ЕстьРусБуквы Или Не(Найти(РусБуквы(), ВРег(Символ)) = 0);
            ЕстьРусАналоги = ЕстьРусАналоги Или Не(Найти(РусАналоги(), ВРег(Символ)) = 0);
            ЕстьЛатБуквы   = ЕстьЛатБуквы Или Не(Найти(ЛатБуквы(), ВРег(Символ)) = 0);
            ЕстьЛатАналоги = ЕстьЛатАналоги Или Не(Найти(ЛатАналоги(), ВРег(Символ)) = 0);
        Иначе // конец РусЛатСлово
            Если Не ПустаяСтрока(РусЛатСлово) Тогда
                Если ЕстьРусБуквы И ЕстьЛатБуквы Тогда
                    Возврат Истина; // Неисправляемая комбинация рус./лат. букв
                ИначеЕсли ЕстьРусБуквы И ЕстьЛатАналоги Тогда
                    ИсправленноеСлово = ИсправленноеРусЛатСлово(РусЛатСлово, Истина);
                    Возврат Истина; // Исправленное на русское
                ИначеЕсли ЕстьЛатБуквы И ЕстьРусАналоги Тогда
                    ИсправленноеСлово = ИсправленноеРусЛатСлово(РусЛатСлово, Ложь);
                    Возврат Истина; // Исправленное на латинское
                КонецЕсли;
                РусЛатСлово = "";
             КонецЕсли;
            ЕстьРусБуквы = Ложь; ЕстьРусАналоги = Ложь; ЕстьЛатБуквы = Ложь; ЕстьЛатАналоги = Ложь;
        КонецЕсли;
    КонецЦикла;
    
    Если Не ПустаяСтрока(РусЛатСлово) Тогда
        Если ЕстьРусБуквы И ЕстьЛатБуквы Тогда
            Возврат Истина; // Неисправляемая комбинация рус./лат. букв
        ИначеЕсли ЕстьРусБуквы И ЕстьЛатАналоги Тогда
            ИсправленноеСлово = ИсправленноеРусЛатСлово(РусЛатСлово, Истина);
            Возврат Истина; // Исправленное на русское
        ИначеЕсли ЕстьЛатБуквы И ЕстьРусАналоги Тогда
            ИсправленноеСлово = ИсправленноеРусЛатСлово(РусЛатСлово, Ложь);
            Возврат Истина; // Исправленное на латинское
        КонецЕсли;
        РусЛатСлово = "";
    КонецЕсли;
    Возврат Ложь;
КонецФункции
10 Mikhail Volkov
 
07.05.17
07:55
Процедуру проверял так: сделаю намеренно ошибки в номенклатуре, смотрю исправила или нет. Захотелось проверить сколько уже в базе подобных ошибок. Нашел обработку, которые тоже слова ищет в файлах описания номенклатуры. Решил ее модернизировать, чтобы искала еще слова в текстовых реквизитах: Артикул, Наименование, НаименованиеПолное, Описание. Добавил в форму реквизитов-галочек в каких реквизитах искать слова. А модуль СформироватьОтчет() их не видит!? Поди СКД тоже их не видит? Как сделать чтобы видели?
Здесь можно обсудить любую тему при этом оставаясь на форуме для 1Сников, который нужен для работы. Ymryn