-1

我有一个 TButton 事件处理程序,它在方法完成执行时引发访问冲突或抽象错误。Delphi 然后end.在我的项目源文件中突出显示。该方法成功运行,从数据库中删除了正确的行。

我有在运行时创建的组件。每行包含一个标签、一个“更新”按钮和一个“删除”按钮,它们的名称中包含与之关联的数据库行号。引发错误的事件处理程序用于删除。

procedure TFormInventoryMngmnt.ProductDeleteClick(Sender: TObject);
var
  button : TButton;
  row : integer;

  confirm : integer;
begin
  // Assuming it is button..how else can this be called?
  button := Sender as TButton;

  // Get row
  row := StrToInt(StringReplace(button.Name, 'Delete', '', [rfReplaceAll,  rfIgnoreCase]));

  // Confirm
  confirm := MessageDlg('Are you sure?', mtInformation, [mbYes, mbNo], 0);
  if confirm = mrYes then
  begin
      // Delete row
      UnitSession.Query.SQL.Clear;
      UnitSession.Query.SQL.Add(Format(' DELETE FROM Products WHERE Product_ID = %s ', [IntToStr(row)]));
      UnitSession.Query.ExecSQL;
      buildManagementSection;
  end;

  // FIXME: why is this throwing access / abstract violation
end;

如果您需要更多代码或解释,请发表评论,我会回复您。

谢谢!

更新了代码buildManagementSection

我注释掉了buildManagementSection来自监听器的调用,它没有抛出任何异常。这个错误可能是由下面的方法引起的,但直到现在我从来没有遇到过问题。

procedure TFormInventoryMngmnt.buildManagementSection;
var
  index : integer;
  runningHeight : integer;

  productName : TLabel;
  productUpdate : TButton;
  productDelete : TButton;
const
  MARGIN_TOP  = 35;

  // Left value of labels
  LABEL_LEFT  = 0;

  // Left value of update button
  UPDATE_LEFT = 235;

  // Left value of delete button
  DELETE_LEFT = 315;
begin
  // Run sql query
  UnitSession.Query.SQL.Clear;
  UnitSession.Query.SQL.Add('SELECT Product, Product_ID FROM Products ORDER BY Product_ID');
  UnitSession.Query.Active := true;

  // Remove all components in the manage section
  for index := (ScrollBoxManage.ComponentCount - 1) downto 0 do
  begin
      ScrollBoxManage.Components[index].Free;
  end;

  // No items
  if UnitSession.Query.RecordCount = 0 then
  begin
      productName            := TLabel.Create(ScrollBoxManage);
      productName.Parent     := ScrollBoxManage;
      productName.Caption    := 'No items!';
      productName.Font.Color := clRed;
      productName.Visible    := true;

      exit;
  end;

  // Build form
  UnitSession.Query.First;
  runningHeight := 0;
  for index := 0 to (UnitSession.Query.RecordCount - 1) do
  begin
      // Create components
      productName   := TLabel.Create(ScrollBoxManage);
      productUpdate := TButton.Create(ScrollBoxManage);
      productDelete := TButton.Create(ScrollBoxManage);

      // Set parents
      productName.Parent   := ScrollBoxManage;
      productUpdate.Parent := ScrollBoxManage;
      productDelete.Parent := ScrollBoxManage;

      // Set values
      productName.Caption   := UnitSession.Query.Fields[0].AsString;
      productUpdate.Caption := 'Update';
      productDelete.Caption := 'Delete';

      // Set event handlers
      productUpdate.OnClick := FormInventoryMngmnt.ProductUpdateClick;
      productDelete.OnClick := FormInventoryMngmnt.ProductDeleteClick;

      // Set top position
      productName.Top   := runningHeight + 3;
      productUpdate.Top := runningHeight;
      productDelete.Top := runningHeight;

      // Set button association
      productName.Name   := 'Label' + UnitSession.Query.Fields[1].AsString;
      productUpdate.Name := 'Update' + UnitSession.Query.Fields[1].AsString;
      productDelete.Name := 'Delete' + UnitSession.Query.Fields[1].AsString;

      // Set left position
      productName.Left   := LABEL_LEFT;
      productUpdate.Left := UPDATE_LEFT;
      productDelete.Left := DELETE_LEFT;

      // Set as visible
      productName.Visible   := true;
      productUpdate.Visible := true;
      productDelete.Visible := true;

      runningHeight := runningHeight + MARGIN_TOP;
      UnitSession.Query.Next;
  end;

end;
4

1 回答 1

-2

按钮实例尚未创建!

没必要说

button := Sender as Tbutton

只需在代码中引用原始按钮,因为它在表单的范围内

row := StrToInt(StringReplace(ProductDelete.Name, 'Delete', '', [rfReplaceAll, rfIgnoreCase]));

或者这样做

with TButton(sender) do
row := StrToInt(StringReplace(Name, 'Delete', '', [rfReplaceAll, rfIgnoreCase]));

或者如果你真的想这样做,用一个保存按钮实例的变量,那么你必须先创建它

begin
  button := TButton.Create(Self);
  try
    button := TButton(Sender)
    // your code
  finally
    button.Free
  end
end
于 2013-11-06T17:10:16.460 回答