Проверка валидности ИНН
Не совсем корректная проверка. Например, вполне себе годный ИНН 612101881190 проверку не проходит. Дело в том, что есть один маленький нюанс:
если остаток от деления = 10, то остаток = 0. Кроме того, ИНН12 содержит 2 контрольные цифры. Значит, и проверять желательно обе.
Функция ВалидностьИНН12(пИНН) Перем А[12]; Для i=1 По СтрДлина(пИНН) Цикл А[i]=Число(Сред(пИНН,i,1)); КонецЦикла; //Проверка первого контрольного числа Сумма = А[1]*3 + А[2]*7 + А[3]*2 + А[4]*4 + А[5]*10 + А[6]*3 + А[7]*5 + А[8]*9 + А[9]*4 + А[10]*6 + А[11]*8; Остаток = Сумма % 11; Если Остаток = 10 Тогда Остаток = 0; КонецЕсли; Если А[12] <> Остаток Тогда Возврат 0; КонецЕсли; //Проверка второго контрольного числа Сумма = А[1]*7 + А[2]*2 + А[3]*4 + А[4]*10 + А[5]*3 + А[6]*5 + А[7]*9 + А[8]*4 + А[9]*6 + А[10]*8; Остаток = Сумма % 11; Если Остаток = 10 Тогда Остаток = 0; КонецЕсли; Если А[11] = Остаток Тогда Возврат 1; Иначе Возврат 0; КонецЕсли; КонецФункции Функция ВалидностьИНН10(пИНН) Перем А[10]; Для i=1 По СтрДлина(пИНН) Цикл А[i]=Число(Сред(пИНН,i,1)); КонецЦикла; Сумма=А[1]*2+А[2]*4+А[3]*10+А[4]*3+А[5]*5+А[6]*9+А[7]*4+А[8]*6+А[9]*8; Остаток = Сумма % 11; Если А[10]=Остаток Тогда Возврат 1; Иначе Возврат 0; КонецЕсли; КонецФункции Функция глВалидностьИНН(тИНН) Экспорт тИНН=СокрЛП(тИНН); Если СтрДлина(тИНН)=10 Тогда Возврат ВалидностьИНН10(тИНН); ИначеЕсли СтрДлина(тИНН)=12 Тогда Возврат ВалидностьИНН12(тИНН); Иначе Возврат 0; КонецЕсли; КонецФункции
Если Остаток = 10 Тогда Остаток = 0; КонецЕсли;
а в Функция ВалидностьИНН10(пИНН) не добавил.
у меня масса клиентов с реальными ИНН выпала с ошибкой.
вот мой вариант, т.е. не мой. измененный
Функция ВалидностьИНН12(пИНН) Перем А[12]; Для i=1 По СтрДлина(пИНН) Цикл А[i]=Число(Сред(пИНН,i,1)); КонецЦикла; //Проверка первого контрольного числа Сумма = А[1]*3 + А[2]*7 + А[3]*2 + А[4]*4 + А[5]*10 + А[6]*3 + А[7]*5 + А[8]*9 + А[9]*4 + А[10]*6 + А[11]*8; Остаток = Сумма % 11; Если Остаток = 10 Тогда Остаток = 0; КонецЕсли; Если А[12] <> Остаток Тогда Возврат 0; КонецЕсли; //Проверка второго контрольного числа Сумма = А[1]*7 + А[2]*2 + А[3]*4 + А[4]*10 + А[5]*3 + А[6]*5 + А[7]*9 + А[8]*4 + А[9]*6 + А[10]*8; Остаток = Сумма % 11; Если Остаток = 10 Тогда Остаток = 0; КонецЕсли; Если А[11] = Остаток Тогда Возврат 1; Иначе Возврат 0; КонецЕсли; КонецФункции Функция ВалидностьИНН10(пИНН) Перем А[10]; Для i=1 По СтрДлина(пИНН) Цикл А[i]=Число(Сред(пИНН,i,1)); КонецЦикла; Сумма=А[1]*2+А[2]*4+А[3]*10+А[4]*3+А[5]*5+А[6]*9+А[7]*4+А[8]*6+А[9]*8; Остаток = Сумма % 11; Если Остаток = 10 Тогда Остаток = 0; КонецЕсли; Если А[10]=Остаток Тогда Возврат 1; Иначе //Сообщить("А[10]: "+СпС(А[10])); //Сообщить("Остаток: "+СпС(Остаток)); Возврат 0; КонецЕсли; КонецФункции Функция глВалидностьИНН(тИНН) Экспорт тИНН=СокрЛП(тИНН); Если СтрДлина(тИНН)=10 Тогда Возврат ВалидностьИНН10(тИНН); ИначеЕсли СтрДлина(тИНН)=12 Тогда Возврат ВалидностьИНН12(тИНН); Иначе Возврат 0; КонецЕсли; КонецФункции
В связи с грядущими событиями, тема как никогда актуальна. Подскажите лучше, какой слэш правильно ставить между ИНН и КПП в справочнике контрагентов, прямой или обратный? Если ни какой не проставить, то в сформированной книге продаж ставится прямой «/», хотя вроде как нужно ставить обратный «\»? Чёт я запутался.
Но функцию можно было загуглить за 3 минуты. Я вывел на отдельную кнопку, проверяю не всех контрагентов, а только тех, по кому есть документы за период. Релизить?
Пока сюда выложу код. Если к ночи будут силы и тут будет интерес — сделаю нормальную публикацию.
На форму обработки 2 даты, ДатаНачала и ДатаКонца. В процедуре ВыбратьКонтрагентовПоДокументамЗаПериод укажите свои виды документов (у меня нетиповая конфа).
Функция КонтрольнаяСуммаИНН(n,inn)
Перем checksum[11];
checksum[1]=3;
checksum[2]=7;
checksum[3]=2;
checksum[4]=4;
checksum[5]=10;
checksum[6]=3;
checksum[7]=5;
checksum[8]=9;
checksum[9]=4;
checksum[10]=6;
checksum[11]=8;
s=0;
Для i=1 По n-1 Цикл
s=s+Число(Сред(inn,i,1))*checksum[12-n+i];
КонецЦикла;
Возврат s%11%10;
КонецФункции //КонтрольнаяСуммаИНН()
Функция лПроверитьИНН(Знач inn) //Экспорт
inn=СокрЛП(Строка(inn));
len=СтрДлина(inn);
Если len=10 тогда
Если Число(Сред(inn,10,1))<>КонтрольнаяСуммаИНН(10,inn) тогда Возврат 0; КонецЕсли;
ИначеЕсли len=12 then
Если Число(Сред(inn,11,1))<>КонтрольнаяСуммаИНН(11,inn) тогда Возврат 0; КонецЕсли;
Если Число(Сред(inn,12,1))<>КонтрольнаяСуммаИНН(12,inn) тогда Возврат 0; КонецЕсли;
ИначеЕсли len<>0 Тогда
Сообщить(«inn» + inn);
Возврат 0;
КонецЕсли;
Возврат 1;
КонецФункции //глПроверитьИНН()
Процедура ВыбратьКонтрагентовПоДокументамЗаПериод(ТаблицаКонтрагентовДляПроверкиИНН, ДатаНачала, ДатаКонца)
Перем Запрос, ТекстЗапроса;
//Создание объекта типа Запрос
Запрос = СоздатьОбъект(«Запрос»);
ТекстЗапроса =
«// |Период с ДатаНачала по ДатаКонца;
|Обрабатывать НеПомеченныеНаУдаление;
|Без итогов;
|ТекДок = Документ.РН.ТекущийДокумент, Документ.СФ.ТекущийДокумент;
|Контрагент = Документ.РН.Клиент, Документ.СФ.Контрагент;
//|Условие Контрагент.ВидКонтрагента = &Юрлицо;
|Группировка Контрагент;
|»//>>ЗАПРОС
;
// Если ошибка в запросе, то выход из процедуры
Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
Возврат;
КонецЕсли;
Пока Запрос.Группировка() = 1 Цикл
ТекКонтрагент = Запрос.Контрагент;
Если ТекКонтрагент.ВидКонтрагента = Перечисление.ВидыКонтрагентов.Организация Тогда
ТаблицаКонтрагентовДляПроверкиИНН.НоваяСтрока();
ТаблицаКонтрагентовДляПроверкиИНН.Контрагент = ТекКонтрагент;
ТаблицаКонтрагентовДляПроверкиИНН.ИНН = ТекКонтрагент.ИНН;
ТаблицаКонтрагентовДляПроверкиИНН.КПП = ТекКонтрагент.КПП;
ТаблицаКонтрагентовДляПроверкиИНН.Проверен = 0;
ТаблицаКонтрагентовДляПроверкиИНН.Ошибка = 0;
ИначеЕсли ТекКонтрагент.ВидКонтрагента = Перечисление.ВидыКонтрагентов.ДочернееОбщество Тогда
Сообщить(«Проверьте вид контрагента у » + ТекКонтрагент, «!»);
ИначеЕсли ТекКонтрагент.ВидКонтрагента = Перечисление.ВидыКонтрагентов.ЗависимоеОбщество Тогда
Сообщить(«Проверьте вид контрагента у » + ТекКонтрагент,»!»);
ИначеЕсли ТекКонтрагент.ВидКонтрагента = Перечисление.ВидыКонтрагентов.ЧастноеЛицо Тогда
// У физлиц можно не проверять?
КонецЕсли;
КонецЦикла;
КонецПроцедуры //ВыбратьКонтрагентовПоДокументамЗаПериод(ТаблицаКонтрагентовДляПроверкиИНН, ДатаНачала, ДатаКонца)
//Перем СчДокДляПроверки, ВсегоДокументов;
ТаблицаКонтрагентовДляПроверкиИНН.ВыбратьСтроки();
Пока ТаблицаКонтрагентовДляПроверкиИНН.ПолучитьСтроку() = 1 Цикл
Если лПроверитьИНН(ТаблицаКонтрагентовДляПроверкиИНН.ИНН) = 1 Тогда
ТаблицаКонтрагентовДляПроверкиИНН.Проверен = 1
Иначе
ТаблицаКонтрагентовДляПроверкиИНН.Ошибка = 1;
ТекКонтрагент = ТаблицаКонтрагентовДляПроверкиИНН.Контрагент;
Сообщить(«Ошибка ИНН у организации » + ТекКонтрагент + «, код » + ТекКонтрагент.Код + «, ИНН » + ТекКонтрагент.ИНН);
КонецЕсли;
КонецЦикла;
ТаблицаКонтрагентовДляПроверкиИНН.ВыбратьСтроку(«результат проверки ИНН по списку»);
1с программирование проверка инн
Функция проверяет переданную ей строку с ИНН (10 цифр для юридического и 12 цифр для физического лица) на предмет корректности согласно алгоритму расчета контрольного числа. Возвращает Истина, если всё Ок, иначе Ложь.
Функция ПроверитьИНН(Знач Значение) Экспорт ИНН = СокрЛП(Значение); Если Не ПопыткаПеревестиВЧисло(ИНН) Тогда Возврат Ложь; КонецЕсли; Если СтрДлина(ИНН) = 10 Тогда Коэффициенты = Новый Массив(10); Коэффициенты[0] = 2; Коэффициенты[1] = 4; Коэффициенты[2] = 10; Коэффициенты[3] = 3; Коэффициенты[4] = 5; Коэффициенты[5] = 9; Коэффициенты[6] = 4; Коэффициенты[7] = 6; Коэффициенты[8] = 8; Коэффициенты[9] = 0; КонтрольнаяСумма = 0; Для А = 1 По 10 Цикл Число = Число(Сред(ИНН, А, 1)); КонтрольнаяСумма = КонтрольнаяСумма + Число * Коэффициенты[А - 1]; КонецЦикла; КонтрольноеЧисло = КонтрольнаяСумма % 11; Если КонтрольноеЧисло > 9 Тогда КонтрольноеЧисло = КонтрольноеЧисло % 10; КонецЕсли; Возврат КонтрольноеЧисло = Число(Сред(ИНН, 10, 1)); ИначеЕсли СтрДлина(ИНН) = 12 Тогда Коэффициенты = Новый Массив(12); Коэффициенты[0] = 3; Коэффициенты[1] = 7; Коэффициенты[2] = 2; Коэффициенты[3] = 4; Коэффициенты[4] = 10; Коэффициенты[5] = 3; Коэффициенты[6] = 5; Коэффициенты[7] = 9; Коэффициенты[8] = 4; Коэффициенты[9] = 6; Коэффициенты[10] = 8; Коэффициенты[11] = 0; КонтрольнаяСумма11 = 0; Для А = 1 По 11 Цикл Число = Число(Сред(ИНН, А, 1)); КонтрольнаяСумма11 = КонтрольнаяСумма11 + Число * Коэффициенты[А]; КонецЦикла; КонтрольноеЧисло11 = КонтрольнаяСумма11 % 11; Если КонтрольноеЧисло11 > 9 Тогда КонтрольноеЧисло11 = КонтрольноеЧисло11 % 10; КонецЕсли; Если КонтрольноеЧисло11 <> Число(Сред(ИНН, 11, 1)) Тогда Возврат Ложь; КонецЕсли; КонтрольнаяСумма12 = 0; Для А = 1 По 12 Цикл Число = Число(Сред(ИНН, А, 1)); КонтрольнаяСумма12 = КонтрольнаяСумма12 + Число * Коэффициенты[А - 1]; КонецЦикла; КонтрольноеЧисло12 = КонтрольнаяСумма12 % 11; Если КонтрольноеЧисло12 > 9 Тогда КонтрольноеЧисло12 = КонтрольноеЧисло12 % 10; КонецЕсли; Если КонтрольноеЧисло12 <> Число(Сред(ИНН, 12, 1)) Тогда Возврат Ложь; КонецЕсли; Возврат Истина; Иначе Возврат Ложь; КонецЕсли; КонецФункции
С уважением, Владимир Милькин (преподаватель школы 1С программистов и разработчик обновлятора).
Как помочь сайту: расскажите (кнопки поделиться ниже) о нём своим друзьям и коллегам. Сделайте это один раз и вы внесете существенный вклад в развитие сайта. На сайте нет рекламы, но чем больше людей им пользуются, тем больше сил у меня для его поддержки.
Нажмите одну из кнопок, чтобы поделиться: