2010-06-08 27 views
5

D6 prof.Delphi - khôi phục hàng thực tế trong DBGrid

Trước đây chúng tôi đã sử dụng DBISAM và DBISAMTable. Điều đó xử lý RecNo, và nó làm việc tốt với các sửa đổi (Xóa, chỉnh sửa, vv).

Bây giờ chúng tôi đã thay thế bằng ElevateDB, không xử lý RecNo và nhiều lần chúng tôi sử dụng Truy vấn, không phải Bảng.

Truy vấn phải mở lại để xem các sửa đổi.

Nhưng nếu chúng tôi Mở lại Truy vấn, chúng tôi cần định vị lại bản ghi cuối cùng. Xác định vị trí không đủ, vì Grid hiển thị nó trong một hàng khác. Đây là điều rất đáng lo ngại, bởi vì sau khi bản ghi sửa đổi đang chuyển sang hàng khác, bạn khó theo dõi nó, và người dùng ghét điều này.

Chúng tôi tìm thấy mã này:

function TBaseDBGrid.GetActRow: integer; 
begin 
Result := -1 + Row; 
end; 


procedure TBasepDBGrid.SetActRow(aRow: integer); 
var 
bm : TBookMark; 
begin 
if IsDataSourceValid(DataSource) then with DataSource.DataSet do begin 
    bm := GetBookmark; 
    DisableControls; 
    try 
    MoveBy(-aRow); 
    MoveBy(aRow); 
    //GotoBookmark(bm); 
    finally 
    FreebookMark(bm); 
    EnableControls; 
    end; 
end; 
end; 

Ví dụ ban đầu là sử dụng moveby. Điều này làm việc tốt với truy vấn, bởi vì chúng tôi không thể thấy rằng truy vấn mở lại trong nền, điều khiển trực quan không thay đổi vị trí hàng. Nhưng khi chúng tôi có EDBTable, hoặc truy vấn trực tiếp/nhạy cảm, MoveBy là nguy hiểm để sử dụng, bởi vì nếu ai đó xóa hoặc nối thêm một hàng mới, chúng tôi có thể di chuyển vào hồ sơ sai.

Sau đó, tôi đã cố gắng sử dụng BookMark (xem nhận xét). Nhưng kỹ thuật này không hoạt động, bởi vì nó hiển thị bản ghi ở một vị trí Hàng khác ...

Vì vậy, câu hỏi: làm thế nào để buộc cả vị trí hàng và ghi trong DBGrid?

Hoặc loại DBGrid nào có thể định vị lại bản ghi/hàng sau khi Số liệu cơ bản được làm mới?

Tôi tìm kiếm giải pháp thân thiện với người dùng, tôi hiểu chúng, vì tôi đã cố gắng sử dụng DBGrid nhảy qua này, và rất xấu để sử dụng, vì mắt tôi đang nhận ra khi cố tìm bản ghi gốc sau khi cập nhật ... :-(

Cám ơn bạn mỗi sự giúp đỡ, liên kết, thông tin: dd

Trả lời

8

Vì 'MoveBy's đang làm việc cho bạn, hãy sử dụng chúng.

Nhận 'Dấu trang' trước khi đóng tập dữ liệu. Làm công việc của bạn, mở lại tập dữ liệu và sau đó định vị lại bản ghi của bạn trên lưới bằng 'MoveBy's. Khi bạn hoàn tất, hãy lấy một Bookmark khác và so sánh nó với trang trước đó với DataSet.CompareBookmarks. Nếu kết quả là 0 tốt, nếu không, chỉ sau đó phát hành một 'GotoBookmark' cho bookmark trước đó.

Bằng cách này, miễn là người dùng khác chưa xóa/chèn bản ghi, lưới điện của bạn sẽ không có vẻ bị giật, và nếu đây không phải là trường hợp ít nhất bạn sẽ có cùng một bản ghi.


chỉnh sửa: Dưới đây là một số mẫu mã mà nên đặt lại vị trí các bản ghi được chọn trong địa điểm chính xác ngay cả khi đã có xóa/chèn trong tập dữ liệu. Lưu ý rằng mã bỏ qua việc vô hiệu hóa/bật điều khiển và trường hợp đặc biệt khi có ít bản ghi để điền vào lưới để đơn giản.

type 
    TAccessDBGrid = class(TDBGrid); 

procedure TForm1.Button1Click(Sender: TObject); 
var 
    BmSave, Bm: TBookmark; 
    GridRow, TotalRow: Integer; 
begin 
    GridRow := TAccessDBGrid(DBGrid1).Row; 
    TotalRow := TAccessDBGrid(DBGrid1).RowCount; 
    BmSave := DBGrid1.DataSource.DataSet.GetBookmark; 
    try 

    // close dataset, open dataset... 

    if DBGrid1.DataSource.DataSet.BookmarkValid(BmSave) then 
     DBGrid1.DataSource.DataSet.GotoBookmark(BmSave); 
    Dec(TotalRow); 
    if GridRow < TotalRow div 2 then begin 
     DBGrid1.DataSource.DataSet.MoveBy(TotalRow - GridRow); 
     DBGrid1.DataSource.DataSet.MoveBy(GridRow - TotalRow); 
    end else begin 
     if dgTitles in DBGrid1.Options then 
     Dec(GridRow); 
     DBGrid1.DataSource.DataSet.MoveBy(-GridRow); 
     DBGrid1.DataSource.DataSet.MoveBy(GridRow); 
    end; 
    Bm := DBGrid1.DataSource.DataSet.GetBookmark; 
    try 
     if (DBGrid1.DataSource.DataSet.BookmarkValid(Bm) and 
      DBGrid1.DataSource.DataSet.BookmarkValid(BmSave)) and 
      (DBGrid1.DataSource.DataSet.CompareBookmarks(Bm, BmSave) <> 0) then 
     DBGrid1.DataSource.DataSet.GotoBookmark(BmSave); 
    finally 
     DBGrid1.DataSource.DataSet.FreeBookmark(Bm); 
    end; 
    finally 
    DBGrid1.DataSource.DataSet.FreeBookmark(BmSave); 
    end; 
end; 
1

Store giá trị (s) của lĩnh vực trọng điểm duy nhất của bạn (s) trước khi đóng cửa và mở lại truy vấn, sau đó Locate vào hồ sơ sau DisableControls/EnableControls để ngăn cập nhật màn hình.

+0

Xin chào! Như tôi thấy không. GotoBookMark là giống nhau mà Xác định vị trí ở đây, bởi vì chúng tôi là sau khi mở. Nhưng hàng lưới thực tế không giống nhau, vì vậy Disable không ngăn Grid hiển thị bản ghi ở vị trí khác. MoveBy là tốt, nhưng tôi cần Xác định vị trí ở đây. Nhưng nếu tôi sử dụng xác định vị trí, hàng Grid thay đổi ... Ví dụ: xay hiển thị bản ghi 127 trong hàng 4. Khi tôi mở lại bằng di chuyển, nó cũng ở hàng 4. Khi tôi sử dụng Định vị/Dấu trang, nó là 3, 2, 5 - ngẫu nhiên, nơi tôi có thể xem bản ghi thực tế ... :-( – durumdara

+1

Người dùng 2 Chèn/Xóa một hàng và các bản ghi đã lưu của Người dùng 1 sẽ không chính xác. Đó là những gì TOndrej đang cố gắng trợ giúp bạn tránh –

0

Đoạn mã đơn giản xuất hiện trong tâm trí của tôi:

procedure DoRefresh(Dataset: TDataset); 
var 
    bkm: TBookmark; 
begin 
    Dataset.UpdateCursorPos; 
    bkm := Dataset.GetBookmark; 
    Dataset.DisableControls; 
    try 
    Dataset.Refresh; //refresh dataset if it's open 

    if Dataset.BookmarkValid(bkm) then 
    begin 
     Dataset.GotoBookmark(bkm); 
    end; 
    finally 
    Dataset.EnableControls; 
    Dataset.FreeBookmark(bkm); 
    end; 
end; 
+0

Hi tôi sử dụng thói quen như thế này:.! aRow = Grid.GetRow(); Query.ReOpen; SetActRow (aRow); Vì vậy, điều này không được đánh dấu vấn đề, đây là DBGrid Row vấn đề ... – durumdara

+0

DBGrid gì bạn đang sử dụng? Tiêu chuẩn TDBGrid không có tài sản GetRow Tôi nghi ngờ rằng đây là vấn đề DBGrid. s bản ghi hoạt động là bản ghi hoạt động hiện tại trong tập dữ liệu. – Linas

0

Vị trí ghi phụ thuộc nhiều vào thứ tự sắp xếp của kết quả bạn nhận được từ đối tượng Truy vấn/Bảng. Nếu bạn không đặt hàng, đơn đặt hàng bạn nhận được từ máy chủ được xác định và không thể đảm bảo rằng các bản ghi có cùng thứ tự khi mở lại truy vấn, ngay cả khi không có thay đổi nào xảy ra. Ít nhất trong MSSQL và Firebird, kết quả có các mệnh lệnh khác nhau nếu không có mệnh đề Theo mệnh đề.

Để định vị lại, tôi nghĩ rằng giải pháp TOndrej là giải pháp an toàn nhất - sử dụng khóa chính của kết quả của bạn để định vị lại lưới trên bản ghi bên phải.

Các vấn đề liên quan