Продолжая серию статей про преобразование отчетности НБУ в "нормальный" для компьютера вид, мы коснемся распространенного вида отчета по Форме №611. Данная форма содержит значения экономических нормативов (кроме нормативов риска открытой валютной позиции), за определенный период. Кроме этого, форма содержит расчет средних значений нормативов (по эксклюзивному алгоритму национального банка) и количество нарушений, допущенных в периоде.
      По сравнению со стандартными файлами типа #1 и #2, методика обработки, которых была описана в одной из предыдущих статей, основной проблемой этой формы является ее текстовое, в полном смысле этого слова, представление. Я имею в виду все эти шапки, подписи и рамки таблицы в формате DOS.
Некоторое неудобство доставляет также то, что нормативы, как показывает практика, иногда меняются Национальным банком.
      Учитывая все эти сложности, я попытался сделать универсальный модуль класса, способный вытягивать данные из формы №611 независимо от того за какой период она формировалась и какие нормативы в ней учтены.
      Теперь про практическое использование. Затягивание формы нормативов собственного банка может понадобиться редко. А вот когда формы рассылаются сотнями банков-контрагентов, автоматизация их обработки существенно облегчает жизнь. Например, минимальные требования Положения НБУ "Про порядок формирования и использования резерва для возмещения возможных убытков по кредитным операциям банков" гласят, что класс банка-заемщика определяется в соответствии со значениями нормативов адекватности регулятивного и основного капитала.
      К статье прилагается файл-пример, который можно скачать по этой ссылке.
      Откройте этот файл и выберите любой файл отчетности (обычно их имя начинается с S3). Запущенный макрос загрузит все значения нормативов, средние значения и количество нарушений по каждому из них.
      Рассмотрим описание модуля класса NBU_Norms, который входит в файл-пример.
      Свойства:
      Path As String - полное имя файла, включая путь;
      Dates As Variant - возвращает массив дат, которые содержит загруженный файл;
      NormsName As Variant - возвращает масив названий нормативов, содержащихся в загруженном файле;
      Методы:
      OpenFile() As Boolean - открывает файл в соответствии со значением свойства Path. Возвращает True, если файл открыт без ошибок, иначе - False;
      GetValue(ByVal NormName As String, ByVal NormDate As Date) As Double - возвращает значение норматива по указанному имени NormName и дате Date;
      GetAverange(ByVal NormName As String) As Double - возвращает среднее значение норматива по указанному имени NormName;
      GetViolation(ByVal NormName As String) As Integer - возвращает количество нарушений норматива по указанному имени NormName.
      Три предидущих метода возвращают &hFFFF (шестнадцетиричное значение) в случае ошибки.
      Рассмотрим небольшой пример. Он не очень практичный, но зато понятный. Более "продвинутый" пример содержится в коде рабочей книги (обработчик события CommandButton1_Click).
Private Sub Example()
      Dim NormsFile As New NBU_Norms 'Создание экземпляра класса
      Dim DatesCount As Integer 'Количество дат
      Dim NormsCount As Integer 'Количество нормативов
      Dim Dates As Variant 'Массив дат
      Dim NormsName As Variant 'Массив имен нормативов
      Dim i As Integer, j As Integer 'Счетчики
      Dim strTmp As String 'Строковый буфер
      Dim dblTmp As Double 'Буфер значений
      With NormsFile
            .Path = "c:\s3300402.022" 'Путь к файлу
            'Открываем файл. В случае неудачи - выход из процедуры
            If Not .OpenFile Then Exit Sub
            'Загружаем и распечатываем имена нормативов
            NormsName = .NormsName
            NormsCount = UBound(NormsName)
            strTmp = "Дата "
            For i = 1 To NormsCount
                  strTmp = strTmp & NormsName(i) & "; "
            Next i
            Debug.Print strTmp
            'Последовательно загружаем и распечатываем значения нормативов
            Dates = .Dates
            DatesCount = UBound(Dates)
            For j = 1 To DatesCount
                  strTmp = Format$(Dates(j), "dd.mm.yy") & " "
                  For i = 1 To NormsCount
                        dblTmp = .GetValue(NormsName(i), Dates(j))
                        If dblTmp = &HFFFF Then Exit Sub 'Выход в случае ошибки
                        strTmp = strTmp & Format$(dblTmp, "0.00") & "; "
                  Next i
            Debug.Print strTmp
            Next j
            'Загружаем и распечатываем средние значения
            strTmp = "Сред. "
            For i = 1 To NormsCount
                  dblTmp = .GetAverange(NormsName(i))
                  If dblTmp = &HFFFF Then Exit Sub
                  strTmp = strTmp & Format$(dblTmp, "0.00") & "; "
            Next i
            Debug.Print strTmp
            'Загружаем и распечатываем количество нарушений
            strTmp = "Наруш. "
            For i = 1 To NormsCount
                  dblTmp = .GetViolation(NormsName(i))
                  If dblTmp = &HFFFF Then Exit Sub
                  strTmp = strTmp & Format$(dblTmp, "0") & "; "
            Next i
            Debug.Print strTmp
      End With
End Sub
      Нужно признаться, что табличка получилась не очень ровная :-) но зато результат на лицо!