Shiz
Shiz

Reputation: 693

Visual FoxPro: Delete row in grid

I have a grid that have 3 columns, column 1 and 2 are textbox, button in the 3rd (for delete).

What I wanted to achieve is when the grid have records, and I click the button in the 3rd column, the row will marked as deleted. Unfortunately it's not working for me and it deletes the last row only.

This is my code for table updating:

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

Some codes inside delete button:

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

Upvotes: 2

Views: 3711

Answers (1)

Cetin Basoz
Cetin Basoz

Reputation: 23797

You are saying you have been searching this for hours including popular sites and cannot find the answer. FWIW, most popular sites for VFP are foxite.com and levelextreme.com. Levelextreme.com doesn't support internet searches AFAIK and have a paid subscription option, besides free subscription. Both sites have the answer to this problem many times as I was one of those who posted sample code for this many times on both of those sites.

What you need is a "DELETE" command, either xBase DELETE or SQL-delete. ie: Assuming grid's record source is 'myCursor':

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

Or SQL-Delete:

*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

In both cases, the record would be marked for deletion. If:

Set deleted OFF

is the current setting (default), then the deleted record would continue to show in the grid, with a black mark on "DeletedMark".

For it to go away you need 2 things: 1) Set deleted setting should be set. It is scoped to current data session. So it is better to set it in dataenvironemt.BeforeOpenTables or Form.Load.

Set deleted ON

2) You should select grid's record source and then refresh.

Here is a working, tested code that shows how to do that:

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

Some notes: Do not use grid properties and methods, like RemoveObject for cases like these. Remember, in most cases, you do the operation on grid's record source cursor itself, not the grid object. DeleteMark though useful sometimes (just to delete a row by clicking it), doesn't have an importance IMHO. Personally, I remove it in my grids. DeleteMark = .f..T. just sets that special column's visibility.

Again, do not use RemoveObject on operations like this. Thisform.Grid.RemoveObject(thisform.Grid.ActiveRow) is a meaningless command in fact. .ActiveRow would return an integer (in case there is an ActiveRow), and removeObject expects an object 'name' as string. Suppose you had it, what would it really remove? A grid is just a visual layout on top of a record source, you would be removing something from the visual layout (like a view window to underlying data).

Append blank, replace is totally obscure to me in this case. Actually, in real life, I would list that 'Append blank\Replace' in 'never to use commands'. That is something buried in ancient Foxpro 2.x days (over 20+ years have passed). It is prone to errors in multiuser scenarios, hard to showcase, but you may end up doing a replace on a different row than you think. As simple and safe alternative is doing an SQL-Insert. ie:

Instead of doing this: (assuming current alias is myCursor)

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

Do this:

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

Despite xBase version (append\replace), this SQL version is a single command and atomic (and much more readable IMHO).

HTH

Upvotes: 1

Related Questions