Скрипт трансформации Kofax VBA для обновления значения поля - PullRequest
0 голосов
/ 18 января 2020

Я не очень использую технологии Kofax, и у меня есть форма преобразования Kofax с полями на 2 разных вкладках. Вот резюме этой формы, в которой я должен взаимодействовать в процессе проверки.

enter image description here

Среди этих полей я пытаюсь обновить содержимое некоторых из них с помощью правила проверки на этапе проверки. Я просто создал правило проверки нескольких полей и правильно сопоставил поля.

enter image description here

Был предложен базовый сценарий c для проверки, если поля действительный или нет. Основываясь на этом скрипте, я попробовал несколько логи c. Цель состоит в том, чтобы установить содержимое поля (которое является пустым и обязательным) на основе базового условия c во втором поле. Моя цель (позже) будет заполнить / обновить поля на основе значения поля «Siret» с помощью вызова базы данных. Мое правило проверки таково: я проверяю длину строки «Siret» (это должна быть строка из 14 символов). Если это правда, я устанавливаю Validation в true и устанавливаю для другого поля значение.

Private Sub Validation_Validate(ByVal ValItems As CASCADELib.CscXDocValidationItems, ByVal pXDoc As CASCADELib.CscXDocument, ByRef ErrDescription As String, ByRef ValidField As Boolean)
   Dim strNAF As String
   Dim strSiret As String

   strNAF = ValItems.Item("NAF").Text
   strSiret = ValItems.Item("Siret").Text

   ' enter your own validation rule here
   If Len(strSiret) <= 14 Then
      pXDoc.Fields.ItemByName("NAF").Text = "GOOD JOB"
      ValidField = True
   Else
      ValidField = False
      ErrDescription = "Describe the error here"
   End If
End Sub

Эта проверка должна происходить, когда я нажимаю клавишу ввода в поле ввода «Siret». Кажется, это не работает на самом деле. Интересно, что происходит на этом этапе?

Ответы [ 2 ]

2 голосов
/ 21 января 2020

Лучшее место для изменения значения поля зависит от вашего варианта использования. Модули преобразования Kofax следуют определенной схеме, и вы всегда должны стараться следовать ей. Например, когда вы обнаруживаете, что вставляете код в метод AfterExtract, вы должны пересмотреть его - почти всегда есть лучший способ. Для tl; dr просто перейдите к Где установить значения?

Естественный порядок

Когда вы наблюдаете поле в Validation, вот что происходит за кулисами:

  1. Локатор обнаруживает информацию (т. Е. Одну или несколько альтернатив).
  2. Локатор назначается полю. Поле всегда будет содержать самую верхнюю альтернативу. По умолчанию ваше поле будет действительным, если существует только одна достоверная альтернатива, или если вторая лучшая альтернатива имеет на 20% меньшую достоверность.
  3. Ваше поле может иметь или не иметь связанный с ним форматировщик. Модуль форматирования может сделать поле недействительным (или даже действительным, если необходимо)
  4. Ваше поле может быть частью одного или нескольких правил проверки. Правила проверки могут сделать поля действительными или недействительными, но они запускаются только в случае успешного форматирования.

Пример

Вот пример. Представьте, что вы хотите определять даты, и вы хотите, чтобы они были в формате базы данных (ггггММдд). Даты в ваших документах представлены в формате США (MM / dd / yyyy), и их две, но у первой помимо ключевого слова есть «дата счета».

  1. Вы настраиваете локатор формата подобрать даты вместе с ключевым словом. Локатор дает две альтернативы: 01/20/2020 при 100% и 01/10/2020 при 0%.
  2. Поскольку вторая альтернатива не рассматривается (порог ниже 10%), поле будет содержать первую one.
  3. Так как первая альтернатива для поля достоверна (80%), применяется форматирование. Форматировщик изменяет значение поля на 20200120, и поле все еще действует.
  4. Вы настраиваете метод проверки даты и используете этот метод для поля. Вы проверяете дату в будущем или нет, и скажем, сегодня 19 января. Поле теперь недействительно, поскольку 20200120 - это один день в будущем.

Это возвращает нас к исходному вопросу - где вы меняете значение поля? Изменение его в сценарии проверки возможно, но имейте в виду, что это нарушает естественный порядок вещей. Еще хуже, если форматирование не удастся, во-первых, ваш код никогда не выполнится.

Где установить значения?

В зависимости от варианта использования, вот мои рекомендации:

  • Вам необходимо установить значение динамического c, получить значения из внешней системы или что-либо еще, что не зависит от другого поля / значения в KTM: создайте локатор сценариев и свяжите его с вашим полем. В скрипте создайте новую альтернативу и установите для нее желаемое значение. Вы даже можете сделать это зависимым от других локаторов (поскольку локаторы выполняются последовательно), но не от других полей (поскольку поля заполняются ПОСЛЕ того, как сработали все локаторы).
  • Вы хотите нормализовать значения. Например, дни недели должны быть представлены буквами (SUN, MON, TUE и так далее). Вы по-прежнему хотите, чтобы ваши пользователи вводили цифры c (1 = SUN, 2 = MON, 3 = TUE). Создайте скрипт форматирования и свяжите его с вашим полем. Преимущество здесь в том, что вам не нужно повторяться (например, в локаторе скриптов и позже в валидации).
  • Вы хотите изменить значения в зависимости от взаимодействия с пользователем. При проверке можно использовать любое событие (например, ButtonClicked, AfterFieldChanged или AfterFieldConfirmed), просто имейте в виду, что некоторые из них не поддерживаются проверкой тонкого клиента (например, AfterFieldChanged). Имейте в виду, что вы хотите изменить указатель, а не само поле, поскольку методы проверки могут использоваться любым количеством полей. В вашем примере pXDoc.Fields.ItemByName("NAF").Text = "GOOD JOB" будет нарушать этот принцип (то есть делать методы проверки повторно используемыми - ваше правило теперь привязано к полю NAF). Вместо этого измените объект проверки; например, ValItems.ItemByName("NAF").Text = "GOOD JOB". Также имейте в виду, что изменение поля в этой точке НЕ вызовет автоматически средство форматирования, связанное с вашим полем, поэтому обязательно укажите значение, которое уже отформатировано. Однако вы можете вызвать форматирование в скрипте вручную.

Ваше требование

Теперь вернемся к исходному требованию:

Цель состоит в том, чтобы установить содержимое поля (которое является пустым и обязательным) на основе базового условия c во втором поле. Моя цель (позже) будет заполнить / обновить поля на основе значения поля «Siret» с помощью вызова базы данных. Мое правило проверки таково: я проверяю длину строки «Siret» (это должна быть строка из 14 символов). Если это так, я устанавливаю значение «Проверка» в значение «истина» и задаю для другого поля значение.

Это зависит от того, хотите ли вы, чтобы пользователи могли изменять второе поле во время проверки. Если нет, go для локатора скрипта. Обратите внимание, что локаторы сценариев могут иметь два подполя, и каждое подполе может быть назначено отдельному полю.

Если ваши пользователи смогут изменить его, go для проверки многополевых сценариев. Оба поля должны быть частью проверки, и первое, что вы должны сделать, - это проверка длины. Затем, если Siret содержит более 14 символов, выполните вызов базы данных.

Слово о DRY и General Design

Не зная ваших точных требований, вот некоторые мысли о возможности повторного использования , Допустим, что Siret не всегда вводится пользователями вручную - фактически, локатор может подобрать указанный текст. Здесь вы хотите создать конкретный c метод для вызова базы данных и возврата результата. Обратите внимание, что KTM имеет встроенную поддержку реляционных баз данных, и вы даже можете получить доступ к этой модели в сценарии.

Другой альтернативой является использование локальных или удаленных нечетких баз данных вместе с локатором баз данных (опять же, если присутствует Siret в вашем документе).

0 голосов
/ 22 января 2020

Благодаря Вольфгангу и моей команде я наконец решил свою проблему. Вот код, используемый для управления этим:

Private Sub ValidationForm_AfterFieldConfirmed(ByVal pXDoc As CASCADELib.CscXDocument, ByVal pField As CASCADELib.CscXDocField)

   Select Case pField.Name
         Case "FieldNameInForm"
            ' simple check if field empty
            If(pXDoc.Fields.ItemByName("FieldNameInForm").Text <> "") Then
               completeForm(pXDoc, pXDoc.Fields.ItemByName("FieldNameInForm").Text)
            End If
      End Select
End Sub


Private Sub completeForm(ByVal pXDoc As CASCADELib.CscXDocument, ByVal myString As String)

   'define required properties
   Dim rs As ADODB.Recordset
   Dim cn As ADODB.Connection
   Dim sqlRequest As String
   Dim dbHostServer As String
   Dim dbUsername As String
   Dim dbPassword As String
   Dim dbName As String
   Dim dbConnString As String

   'Retrieve information for DB Connection (in ScriptVariables.xml)
   dbHostServer = "localhost"
   dbUsername = "root"
   dbPassword = "root"
   dbName = "mydatabase"

   'build the connection string and open connection to database
   dbConnString = "Provider=MSDASQL;Driver={MySQL ODBC 5.3 Unicode Driver};
   dbConnString = dbConnString & "Server=" & dbHostServer & ";"
   dbConnString = dbConnString & "UID=" & dbUsername & ";"
   dbConnString = dbConnString & "PWD=" & dbPassword & ";"
   dbConnString = dbConnString & "database=" & dbName

   'Create recordset and set connection
   'Prapare the db connection
   Set rs = New ADODB.Recordset : : Set cn=New ADODB.Connection

   cn.ConnectionString = dbConnString : cn.Open

   'build query with concatenation
   sqlRequest = "SELECT field1, field2, field3 FROM table"
   sqlRequest = sqlRequest & " where fieldN= '" & myString & "'

   'Execute the SQL request
   Set rs = cn.Execute(sqlRequest)

   ' if the recordset returns a result
   If (rs.EOF Or rs.BOF) Then
      rs.MoveFirst

      pXDoc.Fields.ItemByName("formField1").Text = CStr(rs.Fields("field1"))
      Call ValidStrField("formField1", pXDoc.Fields.ItemByName("field1").Text, pXDoc)

      pXDoc.Fields.ItemByName("formField2").Text = CStr(rs.Fields("field2"))
      Call ValidStrField("formField2", pXDoc.Fields.ItemByName("field2").Text, pXDoc)

      pXDoc.Fields.ItemByName("formField3").Text = CStr(rs.Fields("field3"))
      Call ValidStrField("Commune", pXDoc.Fields.ItemByName("field3").Text, pXDoc)

   'ifthe recordset do not return a value, we set to Undefined
   Else
      pXDoc.Fields.ItemByName("formField1").Text = "Undefined"
      pXDoc.Fields.ItemByName("formField2").Text = "Undefined"
      pXDoc.Fields.ItemByName("formField3").Text = "Undefined"
      MsgBox("No result found in database")
   End If

   ' Close connection & recordset
   rs.Close : Set rs = Nothing
   cn.Close  : Set cn=Nothing    
End Sub

' methods To validate Fields
Private Sub ValidStrField(ByVal StrItem As String,ByVal StrVal As String,ByVal pXDoc As CASCADELib.CscXDocument)
      pXDoc.Fields.ItemByName(StrItem).Text = StrVal
      pXDoc.Fields.ItemByName(StrItem).ExtractionConfident = True
      pXDoc.Fields.ItemByName(StrItem).Confidence = 100.00
      pXDoc.Fields.ItemByName(StrItem).ForcedValid = False
      pXDoc.Fields.ItemByName(StrItem).Valid = True
End Sub

Private Sub UnValidStrField(ByVal StrItem As String,ByVal StrVal As String,ByVal pXDoc As CASCADELib.CscXDocument)
      pXDoc.Fields.ItemByName(StrItem).Text = StrVal
      pXDoc.Fields.ItemByName(StrItem).ExtractionConfident = False
      pXDoc.Fields.ItemByName(StrItem).Confidence = 0.00
      pXDoc.Fields.ItemByName(StrItem).ForcedValid = True
      pXDoc.Fields.ItemByName(StrItem).Valid = False
End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...