我有一个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;
答案 0 :(得分:-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