Склонение ФИО




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2018-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

89 Comments

  1. e.kogan

    Склонение ФИО в виде небольшой процедуры. Писалось студентом-программистом и студентом-лингвистом.

    Перейти к публикации

    Reply
  2. Ёпрст

    Наш ответ чемберлену…

    http://www.forum.mista.ru/topic.php?id=355066

    Reply
  3. Ёпрст

    Гораздо лаконичнее код..и написан задолго до 2003 года…

    Reply
  4. e.kogan

    Лаконичнее. И сумбурнее.

    Кому что нравится.

    Reply
  5. Ёпрст

    Не вижу там никакого сумбура. Код гораздо приятнее. Даже у Рупора проще.

    + должности отрабатывает

    + специфические фамилии

    + каменты

    + примеры использования

    Reply
  6. Abadonna

    (1,2) Слабенький ответик-то получился 😉

    Сообщить(ПадежС(«Кучер»,3,1,1) ); // дательный, мужик, склонять фамилию

    Возвращет: Кучер

    А вот фигушки! КучерУ, ЛебедЮ, Кушниру, КоганУ если речь идет о мужике. А вот для женщины подобные не склоняются.

    А вот у автора вернула в дательном:

    Кучеру Аркадию Арнольдовичу — я

    Кучер Антонине Алексеевне — моя мама

    т.е. абсолютно правильно

    Reply
  7. e.kogan

    (5) Спасибо, хотела сама потестировать предложенное, теперь тратить время не буду.

    Reply
  8. Abadonna

    (6) Да просто уже забодали любители «простых» решений 😉

    А уж если меряться, у кого раньше, то вот: http://1c.proclub.ru/modules/mydownloads/personal.php?cid=111&lid=254

    Написана КучерОМ Аркадием Арнольдовием в 2000 году. Чуток коряво, ибо это было первое, что я написал на 1С ваще. Однако КацА МойшУ АбрамовичА склоняла вполне корректно ;)))

    Reply
  9. e.kogan

    (7) Ну, если уж говорить про Мойш, то правильно — МойшЕ. Или уж Моисей. Уменьшительно-ласкательные склонять задачи не ставилось, всё-таки официальные документы, ага )

    Reply
  10. Abadonna

    (7) Здрасте! Склоняла КОГО? Мойше??? Я не про дательный, а про винительный в данном случае говорил. Что касается какие еврейские уменьшительные, а какие полные — то тут, сорри, я не спец :)))

    Reply
  11. halushka

    Хотел посмотреть, ан рейтингом не вышел. 🙁 Жаль.

    Reply
  12. Abadonna

    (10) Ну держи один плюсик 😉 Щас гляну еще где твои комменты

    Reply
  13. O-Planet

    (10) «Рейтингом не вышел» — это зачОООт! ))))))

    Reply
  14. Vitek

    Доступ C рейтингом не меньше 3 — FAIL.

    Reply
  15. Ёпрст

    (5) Не вопрос. Там есть второй вариант, от Рупора.. там правильнее. 🙂

    Reply
  16. Ёпрст

    (5) И Самое Главное, ВАША неправда:

    Сообщить(Падеж(«Кучер» ,3,1,»1″ )) = «Кучеру»

    Reply
  17. Ёпрст

    Так что, решение правильное, хотя и простое, и не писано «на основании серьёзного лингвистического исследования»

    🙂

    Reply
  18. e.kogan

    (9) МойшА — это некорректно. Это уменьшительное, да к тому же и, скажем так, русифицированное.

    (13) Доступ открыт. Промахнулась с переключателем.

    Reply
  19. Ёпрст

    (17) И всё же потести предложенное, оно рабочее.

    Reply
  20. Abadonna

    Честно признаюсь, что всегда думал что «Мойша» нормальное еврейское имя :))) Без уменьшительного, русифицированного и т.д.

    Reply
  21. Abadonna

    (15) И самое главное, что я тестил Сообщить(ПадежС(«Кучер»,3,1,1) );

    Падеж и еще буковка «С», а не просто Падеж. Когда мне их там сортировать было 😉

    Reply
  22. Ёпрст

    (20) Там же примеры есть в каментах! 🙂

    Reply
  23. Abadonna

    2Ёпрст. Ты завязывай фладить, а давай начинай писать про Dialog Stream и Moxel :))))

    Reply
  24. e.kogan

    (18) Потестила. Хорошооо… Спасибо.

    Reply
  25. e.kogan

    О!

    Меч в творительном — мечЕм, ага ) Нашли-таки мы не ловящееся )

    Reply
  26. Ёпрст

    (24) А вот и фигушки 🙂

    Падеж(«Меч»,5,1,»1″) = «Мечем»

    Reply
  27. e.kogan

    (25) А правильно-то — мечОм!

    Reply
  28. Ёпрст

    (26) Угу, тепереча тестим ваше творение — МечЕм …

    Reply
  29. Ёпрст

    +27 так что ничья… 🙂

    Reply
  30. e.kogan

    (28) Дык я и не спорю 😉 Но предлагали потестить — я и потестила )

    Reply
  31. Ёпрст

    Хотя…

    Мечем Иваным Ивановичем альтернатива

    Мечем Иваном Ивановичем ваш метод

    тоже глюкаво… В общем, есть куда расти.

    Даешь правильные алгоритмы!

    Reply
  32. e.kogan

    (30) Слуушайте… Так это он Ивана неправильно склоняет? Тц-тц-тц… А я-то уж губы раскатала, что хоть кто-то эту титаническую задачу решил на 99%…

    Будем дорабатывать.

    Reply
  33. Ёпрст

    (31) Ну да…:)

    Хотя, кому нужен творительный падеж в 1с-ине ? 🙂

    Reply
  34. e.kogan

    (32) «Договор заключён с Мечом Иваном Ивановичем», например )

    Reply
  35. e.kogan

    (32) Пофиксено: имена, оканчивающиеся на «ан», склоняет неправильно для творительного. Буду разбираться в этой перловке )))

    Reply
  36. Ёпрст

    (34) …Эээ.. в какой обработке пофиксено ? В вашей ? Так там и так было правильно …

    Reply
  37. e.kogan

    (35) Да нет, в предложенной как раз. Но так как собираюсь и её использовать, собираюсь и доводить её до полного блеска.

    Reply
  38. Ёпрст

    (36) Не забудьте выложить потом для тестинга.

    Reply
  39. e.kogan

    Слово «паяц» альтернатива склоняет совсем неправильно. В общем, есть куды ростить.

    Reply
  40. Abadonna

    Как почему-то и думал, так и оказалось 😉

    Сообщить(ПадежФИО(«Черных Петр Петрович»,2));

    Сообщить(ПадежФИО(«Берия Лаврентий Павлович»,2));

    Черныха Петра Петровича

    // как раз случай, когда склонять не надо! А таких фамилий море — сибирские фамилии

    Берия Лаврентия Павловича // а туточки надо БериЮ

    Не надейся на универсальный алгоритм для фамилий, его нет!

    Reply
  41. Abadonna

    А вот как сделано у меня:

    Код
       Если ДвеПоследних="УА" Тогда
          Винительный=Фамилия;//фамилии типа Стуруа
          Дательный=Фамилия;
       КонецЕсли;
       
       Если ДвеПоследних="ИА" Тогда
          Винительный=Фамилия;//фамилии типа Туташхиа
          Дательный=Фамилия;
       КонецЕсли;
       
       Если (ДвеПоследних="ЖА") И (Пол="Ж") Тогда
          Винительный=Фамилия;// женские фамилии типа Ганжа
          Дательный=Фамилия;
       КонецЕсли;
       
       Если ТриПоследних="ДЗЕ" Тогда
          Винительный=Фамилия;//грузинские фамилии типа Гогадзе
          Дательный=Фамилия;
          Перейти ~выход;
       КонецЕсли;
       
       Если ТриПоследних="ИЛИ" Тогда
          Винительный=Фамилия;//грузинские фамилии типа Габошвили
          Дательный=Фамилия;
       КонецЕсли;
              Если (ДвеПоследних="ИХ") ИЛИ  (ДвеПоследних="ЫХ") Тогда
          Винительный=Фамилия;//сибирские фамилии
          Дательный=Фамилия;
       КонецЕсли;
    

    Показать полностью

    Reply
  42. Abadonna

    +(39) Так что лингвист — действительно студент :)))))

    Reply
  43. andrew87

    зря потратили время, в документах достаточно именительного падежа

    Reply
  44. Abadonna

    (42)>зря потратили время, в документах достаточно именительного падежа

    Ну ежели тебе нравится «Доверенность выдана: Иванов Иван Иванович» — тогда достаточно

    А мне нравится, когда «Доверенность выдана: ИвановУ ИванУ ИвановичУ» 😉

    Reply
  45. Crush

    ЗагрузитьВнешнююКомпоненту(«NameDecl.dll»);

    КомпонентаСклоненияФамилий = СоздатьОбъект(«AddIn.NameDeclension»);

    Слово = «Гадя Петрович Хренова»

    НомерПадежа = 2; //Родительный

    Сообщить(КомпонентаСклоненияФамилий.Просклонять(Слово,НомерПадежа));

    //получаем ГадИ Петрович Хреновой

    Компонента есть на диске ИТС, расчитана под восьмёрку, но и в 7.7 нормально работает

    Reply
  46. Crush

    (44) Пропустил точку с запятой, простите 🙂

    У метода «просклонять» есть еще и 30-ий параметр — пол

    Reply
  47. O-Planet

    (40) Мде… Про иначеесли в 2000-м ты похоже не знал 😉 Оно ж даже если нашло ДвеПоследних=»УА», то все остальные тоже станет проверять…

    Reply
  48. Abadonna

    (46) Планет слышал звон, да не знает, где он.

    Не обратил внимание на строку, которую я в одном месте не удалил, а она стоит во ВСЕХ блоках:

    Перейти ~выход;

    И как раз спецом было сделано, чтобы эти блоки тупо копировать, вставлять и изменять, не добавляя ИначеЕсли.

    Лично мне так больше нравится

    Reply
  49. hame1e00n

    Процедура очень интересная, только скачать не могу — рейтинга маловато… плюсик поставил)

    Reply
  50. Diktis

    Для имени «Ольга» в родительном падеже получаем «Ольгы»

    Reply
  51. CheBurator

    а чем Падеж «Крохотулька» с проклаба не нравится?

    Reply
  52. e.kogan

    (50) Приведите ФИО полностью. На «Иванова Ольга Юрьевна» склоняет нормально.

    (51) Дело не в том, что нравится или не нравится. Эта процедура была написана совершенно отдельно.

    Reply
  53. Diktis

    (52) ПадежФИО(«Иванова Ольга Юрьевна», 2) = «Ивановой Ольгы Юрьевны»

    Может я чего-то не понимаю, но откуда взяться другому результату?

    «…

    ИначеЕсли Пол=»Ж» Тогда

    строток=ток.Добавить(); // ирина

    строток.старок=»*а»;

    строток.р=»ы»;

    …»

    Reply
  54. Yashazz

    (51) Этой процедуре уж лет 8, не меньше…

    Насчёт ОльгЫ посмотрим.

    Reply
  55. e.kogan

    (53) Проверяла специально — получается «Ивановой Ольги Юрьевны». Чесслово. Если вводить без отчества — возможно.

    Поправила, теперь Ольга, Инга и т.д. склоняются нормально.

    Reply
  56. nelli_dream

    спасибо автору. мне очень помогла обработочка!

    осталось решить вопрос со склонением профессий и цехов! ::)

    Reply
  57. e.kogan

    (56) Пользуйтесь процедурами Jurer’а. Они это вроде бы умеют.

    Reply
  58. ARL

    Авторам спасибо! Все реальные случаи функция отработала прекрасно. Добавил только точки к инициалам.

    Reply
  59. Andrew_flyer

    Спасибо, молодцы!

    Reply
  60. Поручик

    Раскрасить бы статью.

    Reply
  61. ELInfinito

    Спасибо за алгоритм!

    Reply
  62. e.kogan

    (61) Я передам мужу 🙂

    Reply
  63. kiros

    Спасибо, небольшой тюнинг, если фамилия и.о. определение Ж рода по «а» и «я» в фамилии. Доработал и в работу.

    Еще раз спасибо!

    p.s. А косячки они у всех есть, как можно жить без косячков 😉

    Reply
  64. eli1984

    Сейчас вроде нормально все работает. Спасибо за обработку. пользуюсь.

    Reply
  65. avavadim

    Спасибо за текст обработки, все нормально работает…

    Reply
  66. Joker

    Спасибо, вставил в конфу, все работает

    Reply
  67. fixin

    (0) А теперь проверьте ее моей тестилкой: http://infostart.ru/public/115909/, поищите ошибки.

    А вообще нужно конечно писать склонение на технологии регистров правил, пусть и виртуальных, а не хранящихся в базе. Это будет прорыв. Но за попытку плюсую.

    Reply
  68. IRLes

    Прокопчук Сергей Сергеевич — в родительном падеже получается Прокопчка Сергея Сергеевича

    по идее должно быть Прокопчука Сергея Сергеевича!

    Reply
  69. IRLes

    Удалено

    Reply
  70. fr.myha
    Reply
  71. Stradivari

    Спасибо, огромное)

    Reply
  72. DoctorRoza

    Спасибо, классная штука! 🙂

    Reply
  73. fish249

    Больно уж громоздкий алгоритм. Склоняет всё без ошибок?

    Reply
  74. Horsy

    Огромное спасибо за обработку — это было просто спасением для меня!

    Reply
  75. pvlunegov

    не работает функция в данной статье — происходит зацикливание при попытке удалить множественные пробелы.

    Автор тестировал собственное творение то?

    Reply
  76. pvlunegov

    Исправил в начале функции так:

    // уберем множественные пробелы

    Пока 1=1 Цикл

    ФИО=СокрЛП(СтрЗаменить(ФИО,» «,» «));

    Если Найти(ФИО,» «)=0 Тогда Прервать КонецЕсли;

    КонецЦикла;

    После этого все стало работать. Спасибо!

    Reply
  77. pvlunegov

    При напечатке сообщения в инфостарт два пробела заменяются на один.

    В итоге функция, скопированная из текста статьи, не работает!

    Так что в предыдущем моем комментарии СтрЗаменить(ФИО,» «,» «). В первом » » следует видеть ДВА пробела!

    Reply
  78. e.kogan

    (78) pvlunegov, сами всё поняли 🙂 потому отдельно и прикреплены были файлы.

    Reply
  79. ИНТЕГРА

    В начале сразу не понравилось:

    Пока 1=1 Цикл
    ФИО=СокрЛП(СтрЗаменить(ФИО,» «,» «));
    Если Найти(ФИО,» «)=0 Тогда Прервать КонецЕсли;
    КонецЦикла;

    Заменить на:

    Пока Найти(ФИО,» «) Цикл
    ФИО=СокрЛП(СтрЗаменить(ФИО,» «,» «));
    КонецЦикла;

    А чем типовой вызов склонения из общего модуля не устраивает? 🙂

    Reply
  80. e.kogan

    (80) ИНТЕГРА, да, такой вариант даже был где-то реализован… Писалась эта штука тогда, когда никакого «типового» варианта ещё в помине не было, ну и почитайте комменты выше.

    Reply
  81. Артано

    Функция не умеет склонять существительные с суффиксом ец. Совсем не умеет, ни после закрытого слога, ни после открытого, впрочем как и типовая компонента (похоже что типовая компонента использует тот же алгоритм). Студентам надо было лучше учиться, а то недоучились, а всё туда же — в 1С кодить =)

    Reply
  82. e.kogan

    (82) Плюс по сравнению с компонентой — довольно просто допилить 🙂

    Reply
  83. Артано

    Если когда-нибудь дойдут руки до такого, то не стал бы допиливать, а переписал на иных принципах. А сейчас проще компоненту доработать. Уже реализован механизм переопределения результатов компоненты склонения. Всех физлиц до которых смог дотянуться уже проверил — склоняет верно.

    Reply
  84. r.moschenskiy
    // уберем множественные пробелы
    Пока 1=1 Цикл
    ФИО=СокрЛП(СтрЗаменить(ФИО,» «,» «));
    Если Найти(ФИО,» «)=0 Тогда Прервать КонецЕсли;
    КонецЦикла;

    В этом месте бесконечный цикл, программа зависает намертво.

    Reply
  85. bimy22

    (85) Приведите, пожалуйста, пример, когда у вас сработал бесконечный цикл? Не совсем понимаю, почему у вас зависло.

    Reply
  86. r.moschenskiy

    (78) уже написал — при публикации сообщения на форуме infostart два пробела заменяются на один, в этом вся причина.

    Reply
  87. foxey

    На самом деле в коде ошибка… В первом цикле избавляемся от множественных пробелов, заменяем их на одинарные, а по факту уходим в бесконечный цикл. Цикл надо подправить…

    // уберем множественные пробелы

    Пока 1=1 Цикл

    ФИО=СокрЛП(СтрЗаменить(ФИО,» «,» «));

    Если Найти(ФИО,» «)=0 Тогда Прервать КонецЕсли;

    КонецЦикла;

    в строке ФИО=СокрЛП(СтрЗаменить(ФИО,» «,» «));

    в первой паре кавычек надо прописать два пробела (редактор съедает двойной пробел при помещении текста на сайт)

    и в строке Если Найти(ФИО,» «)=0 Тогда Прервать КонецЕсли;

    тоже надо два пробела написать в кавычках.

    Reply
  88. e.kogan

    (88) так это именно редактор сайта и съел. Было нормально )

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *