Пример: Поиск недействительных ID в поле КЧ должность и заведение вместо них новых должностей

Поиск для примера ведем только по основному совместительству. Кроме того в примере подразумевается, что в КЧ хранятся идентификаторы должностей, то есть в настройке "Настройка -> 6. Общие настройки системы -> 6. Настройки режимов корректировки. -> Способ хранения должностей в КЧ" стоит 0.

Поиск недействительных ID в поле КЧ должность и заведение вместо них новых должностей

FindIncorrectDoljnIDs()
{
   //создаем объект - справочник должностей
   var doljnList=CreateObject("DoljnList");
   // зампомним размер, чтобы после понять сколько добавили
   int doljnListSz=doljnList.Size();
   // список "ключ-значение" найденных в ЛС недействительных идентификаторов должностей 
   // (ключ - старый идентификатор, значение - новый, добавленный взамен)
   // нужен, чтобы одному и тому же старому идентификатору соответствовала одна и та же вновь добаленная должность
   var doljnFoundIDs=CreateObject("MapLong");
   for (int i=0; i<counttn; i++)
   {     
     char ls[LSSTR];
     lsname(tn(i),ls);
     if (lsread(ls,0)==1)
     {
         bool lsCorrected=false;
         // список дат строк в поле КЧ "должность"
         string str=GetListDatBeg("dolgnost","  .  .    ","01.01.2050");
         char value[256]; value="";
         var Par = CreateObject("ParamFuncRW");
         Par.IInitial(str,",",1000);
         for(int i=0;i<Par.Count();i++)
         {
            string DateBeg=Par.Get(i);
            var datB=KDateFromStr(DateBeg);
            // в value - значение поля КЧ должность ("ID;фасеты:дата_увольнения")
            GetKchValue("dolgnost",value,255,datB);
            int idDoljn=atoi(value); 
            // если ID не нулевой и такого ID нет в справочнике должностей - то надо завести
            if (idDoljn!=0 && doljnList.Find(idDoljn)==0)
            {
               // если впервые нашли такой ID - спросим название и добавим должность 
               // если же такой ID уже заводили - просто подставим новый ID (ветка else)
               if (!doljnFoundIDs.IsExist(idDoljn))
               {
                  char newName[DOLJN_NAME_SIZE+1];
                  if (Panel_Zapros("Обнаружена неизвестная должность", "", "Введите название должности :", newName, 
                      DOLJN_NAME_SIZE) == ESC) continue;
                  // добавим должность (последний параметр false - не сохраняем справочник, сохраним потом)
                  var newDoljn=doljnList.AddNewDoljn(to_string(newName), false);
                  if (newDoljn.IsEmpty())
                  {
                      char msg[128];
                      OemToChar("Ошибка добавления должности",msg);
                      MsgBox(msg,"",MB_OK);
                      continue;
                  }
                  // добавляем соответствие "старый ID - новый ID"
                  doljnFoundIDs.Add(idDoljn,newDoljn.GetID());
                  idDoljn=newDoljn.GetID();
               }
               else 
                  idDoljn=doljnFoundIDs.GetValue(idDoljn);

               string partKchValue=StrDoljnWithoutID(value);
               sprintf(value,"%d%s",idDoljn,partKchValue);
               SetKchValue("dolgnost",value,datB);
               lsCorrected=true;
            }
         }
         if (lsCorrected) lswrite(ls,0);
     }     
   }
   // смотрим добавились ли должности
   int added=doljnList.Size()-doljnListSz;
   char msg[128];
   if (added>0)
   {
       // сохраняем справочник должностей (здесь в том числе снимается блокировка справочника)
       doljnList.Save();
       sprintf(msg,"В справочник добавлено %d должностей", added);
       OemToChar(msg,msg);
   }
   else
       OemToChar("Неизвестных должностей не обнаружено",msg);
   MsgBox(msg,"",MB_OK);
}


// вспомогательная функция - возвращает подстроку значения должности в КЧ, пропуская начальные цифры (ID должности)
// то есть для строки "123;1,2:01.01.2000" вернет ";1,2:01.01.2000"
StrDoljnWithoutID(strDoljn)
{
   int i=0;
   while (strDoljn[i])
   {
      if (strDoljn[i]>='0' && strDoljn[i]<='9') i++;
      else break;
   }
   if (strDoljn[i]) return SubStr(strDoljn,i);
   return "";
}