Имя: Пароль:
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
Процедуру проверял так: сделаю намеренно ошибки в номенклатуре, смотрю исправила или нет. Захотелось проверить сколько уже в базе подобных ошибок. Нашел обработку, которые тоже слова ищет в файлах описания номенклатуры. Решил ее модернизировать, чтобы искала еще слова в текстовых реквизитах: Артикул, Наименование, НаименованиеПолное, Описание. Добавил в форму реквизитов-галочек в каких реквизитах искать слова. А модуль СформироватьОтчет() их не видит!? Поди СКД тоже их не видит? Как сделать чтобы видели?