首页 > 解决方案 > Visual FoxPro:删除网格中的行

问题描述

我有一个有 3 列的网格,第 1 列和第 2 列是文本框,第 3 列中的按钮(用于删除)。

我想要实现的是当网格有记录时,我点击第三列的按钮,该行将被标记为已删除。不幸的是,它对我不起作用,它只删除最后一行。

这是我的表更新代码:

SELE descCur2
thisform.item_grid.RecordSourceType = 4
thisform.item_grid.RecordSource = "select * from descCur2 into table descCur2a"
GO top
thisform.item_grid.Refresh

删除按钮内的一些代码:

this.setfocus
*thisform.item_grid.DeleteMark = .T.
Delete
thisform.item_grid.Refresh()
thisform.item_grid.SetFocus

标签: gridviewdelete-rowfoxpro

解决方案


您是说您已经搜索了几个小时,包括热门网站,但找不到答案。FWIW,最受欢迎的 VFP 网站是 foxite.com 和 levelextreme.com。Levelextreme.com 不支持互联网搜索 AFAIK,除了免费订阅外,还有付费订阅选项。这两个站点都多次解决了这个问题,因为我是在这两个站点上多次发布示例代码的人之一。

您需要的是“DELETE”命令,xBase DELETE 或 SQL-delete。即:假设网格的记录源是'myCursor':

select myCursor
* locate the row to delete - by default it is current row in grid
delete

或 SQL 删除:

*Get the ID of current row - assuming ID is the primary key field name
local id
id = myCursor.Id
Delete from myCursor where Id = m.Id

在这两种情况下,记录都会被标记为删除。如果:

Set deleted OFF

是当前设置(默认),则删除的记录将继续显示在网格中,并在“DeletedMark”上带有黑色标记。

要让它消失,你需要两件事:1)应该设置已删除的设置。它的范围是当前数据会话。所以最好在dataenvironemt.BeforeOpenTables或Form.Load中设置。

Set deleted ON

2)您应该选择网格的记录源,然后刷新。

这是一个有效的、经过测试的代码,展示了如何做到这一点:

Public oForm
oForm = Createobject('SampleForm')
oForm.Show()

Define Class sampleForm As Form
    Height=600
    Width=800
    Add Object myGrid As Grid With Height=600,Width=800, Anchor=15, RecordSource='myCursor'

    Procedure Init
        With This.myGrid
            .ColumnCount=3
            With .Columns(.ColumnCount)
                .Newobject('myButton','myButton')
                .CurrentControl = 'myButton'
                .MyButton.Visible = .T.
                .Sparse = .F.
            Endwith
        Endwith
    Endproc

    Procedure Load
        Local ix
        Create Cursor myCursor (Id Int, dummy c(10))
        For ix=1 To 100
            Insert Into myCursor (Id, dummy) Values (m.ix, Sys(2015))
        Endfor
        Locate
        Set Deleted On
    Endproc
Enddefine


Define Class MyButton As CommandButton
    Caption = "Delete Me"
    Procedure Click
        Select myCursor
        Delete
        With this.Parent.Parent
            .Refresh
        endwith
    Endproc
Enddefine

一些注意事项:不要使用网格属性和方法,例如 RemoveObject 用于此类情况。请记住,在大多数情况下,您对网格的记录源光标本身进行操作,而不是网格对象。DeleteMark 虽然有时很有用(只是通过单击删除一行),但恕我直言,它并不重要。就个人而言,我在我的网格中删除它。DeleteMark = .f..T. 只是设置该特殊列的可见性。

同样,不要在这样的操作上使用 RemoveObject。Thisform.Grid.RemoveObject(thisform.Grid.ActiveRow) 实际上是一个没有意义的命令。.ActiveRow 将返回一个整数(如果有 ActiveRow),并且 removeObject 需要一个对象“名称”作为字符串。假设你有它,它会真正删除什么?网格只是记录源顶部的可视布局,您将从可视布局中删除某些内容(例如底层数据的视图窗口)。

在这种情况下,追加空白,替换对我来说是完全模糊的。实际上,在现实生活中,我会在“从不使用命令”中列出“追加空白\替换”。那是在古老的 Foxpro 2.x 时代(已经过去 20 多年)埋葬的东西。它在多用户场景中容易出错,难以展示,但您最终可能会在与您想象的不同的行上进行替换。简单而安全的替代方法是执行 SQL-Insert。IE:

而不是这样做:(假设当前别名是 myCursor)

Append blank
replace name with 'Cetin', Surname with 'Basoz'

做这个:

insert into myCursor (name, surname) values ('Cetin', 'Basoz')

尽管有 xBase 版本(追加\替换),但这个 SQL 版本是单个命令和原子(恕我直言,可读性更强)。

高温高压


推荐阅读