Код: Выделить всё
// Файл StringUtils.vih
#ifndef __StringUtils_vih__
#define __StringUtils_vih__
#component "Utils"
   // Падежи
   const
      csNominativeCase      = 1; // Именительный падеж (Кто? Что?)
      csGenitiveCase        = 2; // Родительный падеж (Кого? Чего?)
      csDativeCase          = 3; // Дательный (Кому? Чему?)
      csAccusativeCase      = 4; // Винительный (Кого? Что?)
      csInstrumentativeCase = 5; // Творительный (Кем? Чем?)
      csPrepositionCase     = 6; // Предложный (О ком? О чём?)
   end;
   
   // Части речи
   const
      csUnknownWord   = 0;    // Неопределенное
      csNounWord      = 1;    // Существительное
      csAdjectiveWord = 2;    // Прилагательное      
   end;
   
   
   // Тип данных -> слово и часть речи  
   public type tWordWithType = record
      WordStr  : string;
      WordType : byte;
   end;   
   
   public type StringArray = array [1..1] of string;   
   public objInterface IStringUtils;
      public:
         ////////////////////////////////////////////////////////////////////////
         // Склонение слов и предложений, сос`тоящих из существительных и прилагательных
         // _case - падеж (константа)
         // stopAfterNoun - прекратить склонение после того как наткнулись на существительное
         ////////////////////////////////////////////////////////////////////////   
         function ConvertWordToCase(str : string; _case : byte) : tWordWithType;
         function ConvertStatementToCase(str : string; _case : byte; stopAfterNoun : boolean = false) : string;   
   end;
   public vipInterface StringUtils implements IStringUtils;  
#end
// Файл StringUtils.vip
#component "Utils"
interface StringUtils;
   
   type tCaseParam = record
      AdjEnd  : array[1..6] of string;
      NounEnd : array[1..7] of string;
   end;   
   
   var _caseParams : array [1..6] of tCaseParam; // Параметры склонений
   ////////////////////////////////////////////////////////////////////////
   // Склонение слов и предложений, состоящих из существительных и прилагательных
   // _case - падеж (константа)
   // onlyAdjective - склонять только прилагательные
   ////////////////////////////////////////////////////////////////////////   
   private function ConvertWordToCaseInternal(str : string; _case : byte; onlyAdjective : boolean) : tWordWithType;
   {      
      result.WordStr  := str;
      result.WordType := csUnknownWord;
      
      if (_case < csGenitiveCase or _case > csPrepositionCase)      
         exit;
         
      var strLen    : byte;
      var cutLen    : byte;
      var ending    : string;
      var wordType  : byte;      
      var caseParam : tCaseParam;
      str       := Trim(str);
      strLen    := Length(str);
      if (str = '' or strLen < 3) // максимальная длина окончания 2 символа
         exit;
         
      caseParam := _caseParams[_case];      
      // 1-й уровень проверки - на прилагательное     
      wordType := csAdjectiveWord;
      cutLen   := 2;      
      ending   := SubStr(str, Byte(strLen - 1), cutLen);
      
      if (UpCase(str) = 'СТОЛОВАЯ') // Исключения
      {
         wordType  := csNounWord;
      }
      case ending of
         'ой': ending := caseParam.AdjEnd[1];
         'ое': ending := caseParam.AdjEnd[2];
         'ый': ending := caseParam.AdjEnd[3]; 
         'ий': ending := caseParam.AdjEnd[4];
         'ее': ending := caseParam.AdjEnd[5];
         'ая': ending := caseParam.AdjEnd[6];
         else { ending := ''; wordType := csUnknownWord; }
      end;
      //}
      // 2 уровень проверки - на существительное
      if (wordType = csUnknownWord and (not onlyAdjective))
      {
         wordType := csNounWord;
         
         if (UpCase(str) = 'БЮРО') // Исключения
         {
            cutLen := 0;
            ending := '';      
         }
         else
         {
            cutLen := 1;
            ending := SubStr(str, strLen, cutLen);        
         
            case ending of
               'б', 'в', 'г', 'д', 'ж', 'з', 'к', 'л', 'м', 'н', 'п', 'р', 'с', 'т', 'ф', 'х', 'ц', 'ч', 'ш', 'щ':
               {
                  ending := caseParam.NounEnd[1];
                  cutLen := 0;
               }
               'а': ending := caseParam.NounEnd[2];
               'е': ending := caseParam.NounEnd[3];            
               'о': ending := caseParam.NounEnd[4];
               'ы': ending := caseParam.NounEnd[5];
               'я': ending := caseParam.NounEnd[6];
               'ь': ending := caseParam.NounEnd[7]; // Здесь ошибка из-за рода: модель и двигатель
               else { ending := ''; wordType := csUnknownWord; }
            end;
         }
      }
      if (wordType <> csUnknownWord)
      {
         result.WordStr  := SubStr(str, 1, Byte(strLen - cutLen)) + ending;
         result.WordType := wordType;
      }
      
      result := result;
   }
   
   ////////////////////////////////////////////////////////////////////////
   // Склонить слово 
   // Слово должно быть в именительном падеже и единственном числе
   ////////////////////////////////////////////////////////////////////////      
   public function IStringUtils.ConvertWordToCase(str : string; _case : byte) : tWordWithType;
   {
      result := ConvertWordToCaseInternal(str, _case, false);
   }
   public function IStringUtils.ConvertStatementToCase(str : string; _case : byte; stopAfterNoun : boolean = false) : string;
   {
      if (_case < csGenitiveCase or _case > csPrepositionCase)
      {
         result := str;
         exit;
      }
      
      result     := '';
      
      var i : byte;
      
      var strLen : word;
      strLen := Length(str);
      
      var curWordLen : byte;
      curWordLen := 0;
      
      var wasNoun : boolean; // Признак того, что нашлось существительное    
      wasNoun := false;
      for (i := 1; i <= strLen; i++)
      {
         var curChar  : char;
         var needCut  : boolean; // Признак того, что необходимо выделять слово для преобразования
         var wasDelim : boolean;
         var cutPos   : byte;
         curChar  := str[i];
         needCut  := false;         
         
         if (curChar = ' ' or curChar = ',') // Проверка на разделитель слов в предложении
         {
            if (curWordLen > 0)
            {
               needCut  := true;
               cutPos   := i - curWordLen;
               wasDelim := true;
            }
            else result += curChar;
         }
         else
         {
            curWordLen++;
            
            if (i = strLen) // Дошли до конца выражения
            {
               needCut := true;
               cutPos  := i - curWordLen + 1;
               wasDelim := false;
            }
         }
         
         if (needCut)
         {
            var wordWithType : tWordWithType;
            wordWithType := ConvertWordToCaseInternal(SubStr(str, cutPos, curWordLen), _case, wasNoun);
            
            result += wordWithType.WordStr + if(wasDelim, curChar, '');
            curWordLen := 0;
            
            if (wordWithType.WordType = csNounWord and i <> strLen)
            {
               wasNoun := true;
               
               if (stopAfterNoun)
               {
                  result += SubStr(str, i + 1, strLen - i);
                  break;
               }
            }
         }
      }
   }   
   
   handleEvent
      cmOnVipLoad:
      {
         /* 
         Окончания прилагательных   
         
         [1] 'ой' // ДеловОЙ
         [2] 'ое' // КрасивОЕ
         [3] 'ый' // КрасивЫЙ
         [4] 'ий' // ТехническИЙ
         [5] 'ее' // ОбщЕЕ
         [6] 'ая' // СчастливАЯ
         
         Окончания существительных
         [1] 'б', 'в', 'г', 'д', 'ж', 'з', 'к', 'л', 'м', 'н', 'п', 'р', 'с', 'т', 'ф', 'х', 'ц', 'ч', 'ш', 'щ' // Отдел
         [2] 'а' // РаботА
         [3] 'е' // ПолЕ           
         [4] 'о' // ОкнО
         [5] 'ы' // НасосЫ
         [6] 'я' // НянЯ
         [7] 'ь' // Модель, двигатель
         */         
         
         var caseParam : tCaseParam;
         ////////////////////////////////////////////////////////////////////////
         // Именительный падеж (кто, что)
         ////////////////////////////////////////////////////////////////////////
         ClearAdvRecord(caseParam);
         _caseParams[1] := caseParam;
         ////////////////////////////////////////////////////////////////////////
         // Родительный падеж (кого, чего)
         ////////////////////////////////////////////////////////////////////////
         ClearAdvRecord(caseParam);
         
         caseParam.AdjEnd[1] := 'ого';
         caseParam.AdjEnd[2] := 'ого';
         caseParam.AdjEnd[3] := 'ого';
         caseParam.AdjEnd[4] := 'ого';
         caseParam.AdjEnd[5] := 'его';
         caseParam.AdjEnd[6] := 'ой';        
         caseParam.NounEnd[1] := 'а';
         caseParam.NounEnd[2] := 'ы';
         caseParam.NounEnd[3] := 'я';
         caseParam.NounEnd[4] := 'а';
         caseParam.NounEnd[5] := 'ов';
         caseParam.NounEnd[6] := 'и';
         caseParam.NounEnd[7] := 'и';
         _caseParams[2] := caseParam;         
         
         ////////////////////////////////////////////////////////////////////////
         // Дательный падеж (кому, чему)
         ////////////////////////////////////////////////////////////////////////
         ClearAdvRecord(caseParam);
         
         caseParam.AdjEnd[1] := 'ому';
         caseParam.AdjEnd[2] := 'ому';
         caseParam.AdjEnd[3] := 'ому';
         caseParam.AdjEnd[4] := 'ому';
         caseParam.AdjEnd[5] := 'ему';
         caseParam.AdjEnd[6] := 'ой';
         caseParam.NounEnd[1] := 'у';
         caseParam.NounEnd[2] := 'е';
         caseParam.NounEnd[3] := 'ю';
         caseParam.NounEnd[4] := 'у';
         caseParam.NounEnd[5] := 'ам';
         caseParam.NounEnd[6] := 'е';
         caseParam.NounEnd[7] := 'и';
         _caseParams[3] := caseParam;
         
         ////////////////////////////////////////////////////////////////////////
         // Винительный падеж (кого, что)
         ////////////////////////////////////////////////////////////////////////
         ClearAdvRecord(caseParam);
         
         caseParam.AdjEnd[1] := 'ого';
         caseParam.AdjEnd[2] := 'ое';
         caseParam.AdjEnd[3] := 'ого';
         caseParam.AdjEnd[4] := 'ий';
         caseParam.AdjEnd[5] := 'ее';
         caseParam.AdjEnd[6] := 'ую';
         caseParam.NounEnd[1] := '';
         caseParam.NounEnd[2] := 'у';
         caseParam.NounEnd[3] := 'е';
         caseParam.NounEnd[4] := 'о';
         caseParam.NounEnd[5] := 'ы';
         caseParam.NounEnd[6] := 'ю';
         caseParam.NounEnd[7] := 'ь';
         _caseParams[4] := caseParam;
         
         ////////////////////////////////////////////////////////////////////////
         // Творительный падеж (кем, чем)
         ////////////////////////////////////////////////////////////////////////
         ClearAdvRecord(caseParam);
         
         caseParam.AdjEnd[1] := 'ым';
         caseParam.AdjEnd[2] := 'ым';
         caseParam.AdjEnd[3] := 'ым';
         caseParam.AdjEnd[4] := 'им';
         caseParam.AdjEnd[5] := 'им';
         caseParam.AdjEnd[6] := 'ой';
         caseParam.NounEnd[1] := 'ом';
         caseParam.NounEnd[2] := 'ой';
         caseParam.NounEnd[3] := 'ем';
         caseParam.NounEnd[4] := 'ом';
         caseParam.NounEnd[5] := 'ами';
         caseParam.NounEnd[6] := 'ей';
         caseParam.NounEnd[7] := 'ью';
         _caseParams[5] := caseParam;
         
         ////////////////////////////////////////////////////////////////////////
         // Предложный падеж (о ком, о чем)
         ////////////////////////////////////////////////////////////////////////
         ClearAdvRecord(caseParam);
         
         caseParam.AdjEnd[1] := 'ом';
         caseParam.AdjEnd[2] := 'ом';
         caseParam.AdjEnd[3] := 'ом';
         caseParam.AdjEnd[4] := 'ом';
         caseParam.AdjEnd[5] := 'ем';
         caseParam.AdjEnd[6] := 'ой';
         caseParam.NounEnd[1] := 'е';
         caseParam.NounEnd[2] := 'е';
         caseParam.NounEnd[3] := 'е';
         caseParam.NounEnd[4] := 'е';
         caseParam.NounEnd[5] := 'ах';
         caseParam.NounEnd[6] := 'е';
         caseParam.NounEnd[7] := 'и';
         _caseParams[6] := caseParam;
      }
   end;
end.
// Использование Test.vip
#component "Test"
interface TestCase;
   
   create view
   as select
      ObjRem.Name,
      FpCO.Name
   from
      ObjRem,
      FpCO;
   handleEvent
      cmInit:
      {
         var strUtils : Utils::IStringUtils;     
         LoadVipRef(strUtils, 'Utils::StringUtils');
         
         _loop ObjRem // FpCO
         {
            var str : string;
            str := ObjRem.Name;  // FpCO.Name
            
            var needStop : boolean; 
            needStop := false; // Для ObjRem = false для FpCO = true
            LogStrToFile('c:\res.log', str + 
                                       Chr(13) + 
                                       strUtils.ConvertStatementToCase(str, csGenitiveCase, needStop) + 
                                       Chr(13) +
                                       strUtils.ConvertStatementToCase(str, csDativeCase, needStop) +
                                       Chr(13) +
                                       strUtils.ConvertStatementToCase(str, csAccusativeCase, needStop) +
                                       Chr(13) +
                                       strUtils.ConvertStatementToCase(str, csInstrumentativeCase, needStop) +
                                       Chr(13) +
                                       strUtils.ConvertStatementToCase(str, csPrepositionCase, needStop) + 
                                       Chr(13));
         }         
         
         ProcessText('c:\res.log', vfRunModal or vfNewTitle or vfToErase or vfMacroSize or vfEscable, 'Отчет');         
      }
   end;
end.
Объект ремонта
----
Система контроля вибрации
Системы контроля вибрации
Системе контроля вибрации
Систему контроля вибрации
Системой контроля вибрации
Системе контроля вибрации
---
Центр ответственности
---
Служба организации общественного питания
Службы организации общественного питания
Службе организации общественного питания
Службу организации общественного питания
Службой организации общественного питания
Службе организации общественного питания
---