You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerBuilder 19中按需屏蔽验证MessageBox弹窗的问题求助

PowerBuilder 19 新建按钮触发多次验证弹窗问题

在文章管理项目中,点击「新建」按钮会显示空的自由格式数据窗口dwc_article,用于录入文章详情(reference、name等字段)。我在dwc_article的ItemFocusChanged事件中添加了验证逻辑:当reference或name为空时弹出「Validation Error」消息框。

但存在以下问题:在表格格式数据窗口dwc_report中选中一行并点击「更新」按钮后,dwc_article会加载该文章详情;此时再点击「新建」按钮,会连续弹出3次验证错误消息框,需要在该场景下屏蔽这些弹窗。


相关脚本

dwc_article 的 ItemFocusChanged 事件脚本

integer li_row
string ls_reference
string ls_name

li_row = This.GetRow()
cb_3.Enabled = false
cb_7.Enabled = false

// Check if the focus is on the reference field
if This.GetColumnName() <> "reference"  then
     // Get the value of the reference field
     ls_reference = This.GetItemString(li_row, "reference")

     // Check if the reference field is empty or has more than 50 characters
     if IsNull(ls_reference) or Trim(ls_reference) = "" or Len(ls_reference) > 50 then
          MessageBox("Validation Error", "Reference field must not be empty and should have 50 characters or less.")
          // Set focus back to the reference field
                     cb_3.Enabled = false
                     cb_7.Enabled = false
          This.SetColumn("reference")
          return 1 // Prevent focus change
     
else
    
end if
end if



li_row = This.GetRow()

// Check if the focus is on the name field
if This.GetColumnName() <> "name" and This.GetColumnName() <> "reference" then
     // Get the value of the name field
     ls_name = This.GetItemString(li_row, "name")
     cb_3.Enabled = false
     cb_7.Enabled = false

     // Check if the name field is empty or has more than 50 characters
     if IsNull(ls_name) or Trim(ls_name) = "" or Len(ls_name) > 50 then
          MessageBox("Validation Error", "Name field must not be empty and should have 50 characters or less.")
          // Set focus back to the name field
          This.SetColumn("name")
          cb_3.Enabled = false
          cb_7.Enabled = false
          return 1 // Prevent focus change
     
else
    cb_3.Enabled = true
    cb_7.Enabled = true
    end if
end if

return 0

「新建」按钮脚本

dwc_article.reset()
dwc_article.insertrow(0)
char reference
dwc_article.scrolltorow(dwc_article.insertrow(0))

// Scroll to the newly inserted row
long ll_new_row
ll_new_row = dwc_article.InsertRow(0)
dwc_article.ScrollToRow(ll_new_row)

// Get the current date
date ld_date_creation
ld_date_creation = today()

string ls_formatted_date
ls_formatted_date = String(ld_date_creation, "yyyy-mm-dd")

// Set the current date to the "date_de_creation" column
dwc_article.SetItem(ll_new_row, "date_de_creation", ls_formatted_date)

bl_btn_new_clicked = true

dwc_article.modify("reference.Protect='0'") // This removes input capability from all columns
       dwc_article.modify("name.Protect='0'")
       dwc_article.modify("prix.Protect='0'")
         dwc_article.modify("date_de_creation.Protect='1'")

「更新」按钮脚本

long ll_row
ll_row = dwc_report.GetSelectedRow(0) // Get the selected row index in dwc_report

if ll_row >= 0 then // If a row is selected
    // Clear existing data in dwc_article
    dwc_article.Reset()
     
     long ll_nextRow
    ll_nextRow = dwc_article.RowCount() + 1

    // Copy data from dwc_report to dwc_article
    dwc_report.RowsCopy(ll_row, ll_row, Primary!, dwc_article, ll_nextRow, Primary!)

    // Disable all inputs in dwc_article
    dwc_article.modify("reference.Protect='1'") 
    dwc_article.modify("name.Protect='0'")
    dwc_article.modify("prix.Protect='0'")
    dwc_article.modify("date_de_creation.Protect='1'")

    // Retrieve data in dwc_article to reflect changes
    //dwc_report.retrieve()
    //dwc_article.retrieve()
else
    MessageBox("No row selected", "Please select a row in the report")
end if

问题根源与解决方案

问题根源

  1. 新建按钮重复插入行:当前「新建」按钮脚本中连续调用了3次InsertRow(0),每次插入行都会触发ItemFocusChanged事件,导致验证逻辑被执行3次,对应弹出3次弹窗。
  2. 验证逻辑未区分手动操作与代码触发:当通过代码(如新建、更新)切换数据或行时,ItemFocusChanged事件依然会执行验证,而此时用户还未开始手动输入,触发验证没有意义。

解决方案

步骤1:修复新建按钮的重复插入问题

删除重复的InsertRow调用,只保留一次插入操作,减少不必要的事件触发:

dwc_article.reset()
// 只保留一次插入行操作
long ll_new_row
ll_new_row = dwc_article.InsertRow(0)
dwc_article.ScrollToRow(ll_new_row)

// Get the current date
date ld_date_creation
ld_date_creation = today()

string ls_formatted_date
ls_formatted_date = String(ld_date_creation, "yyyy-mm-dd")

// Set the current date to the "date_de_creation" column
dwc_article.SetItem(ll_new_row, "date_de_creation", ls_formatted_date)

bl_btn_new_clicked = true

dwc_article.modify("reference.Protect='0'")
dwc_article.modify("name.Protect='0'")
dwc_article.modify("prix.Protect='0'")
dwc_article.modify("date_de_creation.Protect='1'")

步骤2:添加全局标志位控制验证逻辑

在窗口的实例变量中添加一个布尔型变量ib_skip_validation,用于标记是否需要跳过验证:

// 窗口实例变量
boolean ib_skip_validation = false

然后修改「新建」和「更新」按钮脚本,在操作数据窗口前设置标志位为true,操作完成后恢复为false:

  • 新建按钮脚本开头添加:
ib_skip_validation = true

结尾添加:

ib_skip_validation = false
// 手动设置焦点到reference字段,避免自动触发验证
dwc_article.SetColumn("reference")
  • 更新按钮脚本开头添加:
ib_skip_validation = true

结尾添加:

ib_skip_validation = false

步骤3:修改ItemFocusChanged事件的验证逻辑

在验证逻辑执行前先检查ib_skip_validation的值,若为true则直接跳过验证:

integer li_row
string ls_reference
string ls_name

// 跳过代码触发的焦点变化验证
if ib_skip_validation then
    return 0
end if

li_row = This.GetRow()
cb_3.Enabled = false
cb_7.Enabled = false

// Check if the focus is on the reference field
if This.GetColumnName() <> "reference"  then
     // Get the value of the reference field
     ls_reference = This.GetItemString(li_row, "reference")

     // Check if the reference field is empty or has more than 50 characters
     if IsNull(ls_reference) or Trim(ls_reference) = "" or Len(ls_reference) > 50 then
          MessageBox("Validation Error", "Reference field must not be empty and should have 50 characters or less.")
          // Set focus back to the reference field
          cb_3.Enabled = false
          cb_7.Enabled = false
          This.SetColumn("reference")
          return 1 // Prevent focus change
     end if
end if

li_row = This.GetRow()

// Check if the focus is on the name field
if This.GetColumnName() <> "name" and This.GetColumnName() <> "reference" then
     // Get the value of the name field
     ls_name = This.GetItemString(li_row, "name")
     cb_3.Enabled = false
     cb_7.Enabled = false

     // Check if the name field is empty or has more than 50 characters
     if IsNull(ls_name) or Trim(ls_name) = "" or Len(ls_name) > 50 then
          MessageBox("Validation Error", "Name field must not be empty and should have 50 characters or less.")
          // Set focus back to the name field
          This.SetColumn("name")
          cb_3.Enabled = false
          cb_7.Enabled = false
          return 1 // Prevent focus change
     else
        cb_3.Enabled = true
        cb_7.Enabled = true
     end if
end if

return 0

额外优化建议

  • 可以将验证逻辑移到ItemChanged事件中,只在用户修改字段内容后触发验证,而非焦点变化时,这样更符合用户操作习惯。
  • 避免在ItemFocusChanged中强制设置焦点回退,除非是用户手动离开未填写的必填字段时再触发。

内容的提问来源于stack exchange,提问作者Hatem Moalla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 21:28:11