我在CFormView中放置了datagrid控件,但没有和数据库绑定。
然后我动态设置了5列,初始化了列的caption。
但是当我想在表格中添加数据时就出现了问题:
比如我想在第一行第一列中设置一个字符串:
GetRow()总是返回-1;
SetRow()提示rowset invalid;
这是什么原因啊?怎么向表格中动态添加数据,怎么设置表格为可编辑状态? 拜托了。
然后我动态设置了5列,初始化了列的caption。
但是当我想在表格中添加数据时就出现了问题:
比如我想在第一行第一列中设置一个字符串:
GetRow()总是返回-1;
SetRow()提示rowset invalid;
这是什么原因啊?怎么向表格中动态添加数据,怎么设置表格为可编辑状态? 拜托了。
可以通过
setrow(..)
settext(..)
DBGrid 在无绑定模式下的VC++编程内容(只有VB的)。我想把我的心得与别人
分享会是一个好主意。 首先,尽管连随机文档都说它能接受任何类型的变量作为书签,但是好象并不
是那么回事儿。DaoRecordset把SAFEARRAY作为书签(GetBook返回包含
VT_ARRAY | VT_UI1的变量),但它不能与DBGrid一起工作(DBGrid把变量转变
为VT_BSTR)。 它可能会与VT_I4工作的很好,但据说字符串是最好的,所以我
用他们。当然,我把书签转换成字符串再转换回来。 SchedQ是一个通过查询得
来的动态集(CDaoRecordset),如果关于他你有任何bug或是好想法,请跟我分
享您的发现。 啊,对,我几乎忘了!极其重要!如果你从OCX的类库中继承了
RowBuffer类,请修改构造函数,原构造函数得到LPDISPACH作为参数去调用基类
的构造函数,这时第二个参数要设为FALSE(原来隐性地设置为TRUE)。如果不
这样做,当RowBuffer对象被消除时整个程序会崩溃。 补充技巧:记着使用
BeforeColUpdate 和KeyPress事件去验证一个域的输入及相应地过滤键盘的输入。 请不要给我来e-mails,问我关于如何在绑定模式下使用他们的问题。在加入
DBGrid之前加上一个Microsoft Remote Data Control 的对话框,然后花点时
间调整一下它的属性,你就会弄明白如何使用它。 致那些想在运行时改变列
的人:由DBGrid类生成的GetColumns()成员函数是一个真正的GetColumn函数
(返回一个指向单个列的LPDISPATCH---这样你就可以用这个LPDISPATCH来构造
单个列对象,而不是列集的对象)。如果你想获得指向列集的LPDISPATCH,
把GetColumns()该名为GetColumn,然后象下面这样重新写一个GetColumns():
LPDISPATCH CMsDgridCtrl::GetColumns()
{
LPDISPATCH result;
InvokeHelper(0x8,DISPATCH_PROPERTYGET,VT_DISPATCH,(void*)&result,NULL,NULL);
return result;
}
这样你就可以用返回的LPDISPATCH来构造列集对象。 那么现在,往网格中输
入数据、删除纪录、当网格中写操作发生时从网格中获取数据的代码如下所示:
void CMyView::OnUnboundReadDataDbgridMy(LPDISPATCH RowBuf, VARIANT FAR* StartLocation, BOOL ReadPriorRows) {
// TODO: Add your control notification handler code here
RowBuffer buf(RowBuf);
VARIANT varbok;
varbok.vt=VT_ARRAY | VT_UI1;
long Row,RowsFetched;
VARIANT var;
RowsFetched=0;
if(StartLocation->vt==VT_NULL){
if(ReadPriorRows){
try{
SchedQ->MoveLast();
}catch(CDaoException* e){
e->Delete();
}
}else{
try{
SchedQ->MoveFirst();
}catch(CDaoException* e){
e->Delete();
}
}
}else{
//根据StartLocation书签和ReadPriorRows参数找到开始读数据的位置
try{
VectorFromBstr(StartLocation->bstrVal,&varbok.parray);
SchedQ->SetBook(COleVariant(varbok));
if(ReadPriorRows)SchedQ->MovePrev();
else SchedQ->MoveNext();
}catch(CDaoException* e){
e->Delete();
}
}
//把我们的数据集数组转换为DBGrid 用来显示数据的RowBuf对象,
for(Row = 0; RowIsEOF() || SchedQ->IsBOF())break;
var.vt=VT_I4;
var.lVal=SchedQ->m_WorkCodeID;
if(buf.GetColumnCount()>0)buf.SetValue(Row, 0,var);
COleVariant olvi(SchedQ->m_TimeIn);
var=*((LPVARIANT)olvi);
if(buf.GetColumnCount()>1)buf.SetValue(Row, 1,var);
COleVariant olvo(SchedQ->m_TimeOut);
var=*((LPVARIANT)olvo);
if(buf.GetColumnCount()>2)buf.SetValue(Row, 2,var);
// Set book using CurRow which is also our
// array index
var.vt=VT_BSTR;
BstrFromVector(((LPVARIANT)SchedQ->GetBook())->parray,&var.bstrVal);
buf.SetBook(Row,var);
RowsFetched++;
if(ReadPriorRows)SchedQ->MovePrev();
else SchedQ->MoveNext();
}
buf.SetRowCount(RowsFetched);
}
void CMyView::OnUnboundWriteDataDbgridMy(LPDISPATCH RowBuf, VARIANT FAR* WriteLocation)
{
// TODO: Add your control notification handler code here
RowBuffer buf(RowBuf);
VARIANT varbok;
varbok.vt=VT_ARRAY | VT_UI1;
COleVariant var;
CString str;
try{
VectorFromBstr(WriteLocation->bstrVal,&varbok.parray);
SchedQ->SetBook(COleVariant(varbok));
}catch(CDaoException* e){
e->Delete();
buf.SetRowCount(0);
return;
}
//**********************************************************************
//Here was a portion of code that validated the record
//************************************************
//只有被修改过的列更新,否则,值被设置为NULL
try{
SchedQ->Edit();
}
catch(CDaoException* e){
e->Delete();
buf.SetRowCount(0);
return;
}
if(buf.GetValue(0L, 0).vt!=VT_NULL){
var=buf.GetValue(0, 0);
str=CString(var.bstrVal);
SchedQ->m_WorkCodeID=atol(str);
}
if(buf.GetValue(0L, 1).vt!=VT_NULL){
var=buf.GetValue(0, 1);
str=CString(var.bstrVal);
SchedQ->m_TimeIn.ParseDateTime(str);
}
if(buf.GetValue(0L, 2).vt!=VT_NULL){
var=buf.GetValue(0, 2);
str=CString(var.bstrVal);
SchedQ->m_TimeOut.ParseDateTime(str);
}
try{
SchedQ->Update();
}catch(CDaoException *e){
SchedQ->CancelUpdate();
e->Delete();
buf.SetRowCount(0);
}
}
void CMyView::OnUnboundAddDataDbgridMy(LPDISPATCH RowBuf, VARIANT FAR* NewRowBook)
{
// TODO: Add your control notification handler code here
RowBuffer buf(RowBuf);
COleVariant var;
CString str;
NewRowBook->vt=VT_NULL;
//**********************************************************************
//Here was a portion of code that validated the record
//**********************************************************************
try{
SchedQ->AddNew();
SchedQ->Update();
SchedQ->SetBook(SchedQ->GetLastModifiedBook());
SchedQ->Edit();
}catch(CDaoException* e){
e->Delete();
buf.SetRowCount(0);
return;
}
SchedQ->m_EmployeeID=m_pSet->m_EmployeeID;
try{
if(buf.GetValue(0L, 0).vt!=VT_NULL){
var=buf.GetValue(0, 0);
}else{
var.vt=VT_I4;
var.lVal=0;
Column col(m_SchedGrid.GetColumns(var));
var=col.GetDefaultValue();
}
str=(char*)_bstr_t(var.bstrVal);
SchedQ->m_WorkCodeID=atol(str);
if(buf.GetValue(0L, 1).vt!=VT_NULL){
var=buf.GetValue(0, 1);
}else{
var.vt=VT_I4;
var.lVal=1;
Column col(m_SchedGrid.GetColumns(var));
var=col.GetDefaultValue();
}
str=(char*)_bstr_t(var.bstrVal);
SchedQ->m_TimeIn.ParseDateTime(str);
if(buf.GetValue(0L, 2).vt!=VT_NULL){
var=buf.GetValue(0, 2);
}else{
var.vt=VT_I4;
var.lVal=2;
Column col(m_SchedGrid.GetColumns(var));
var=col.GetDefaultValue();
}
str=(char*)_bstr_t(var.bstrVal);
SchedQ->m_TimeOut.ParseDateTime(str);
var.vt=VT_I4;
SchedQ->Update();
}catch(CDaoException *e){
e->Delete();
SchedQ->CancelUpdate();
SchedQ->Delete();
buf.SetRowCount(0);
}
NewRowBook->vt=VT_BSTR;
BstrFromVector(((LPVARIANT)SchedQ->GetBook())->parray,&(NewRowBook->bstrVal));
}
void CMyView::OnUnboundDeleteRowDbgridMy(VARIANT FAR* Book)
{
// TODO: Add your control notification handler code here
VARIANT varbok;
varbok.vt=VT_ARRAY | VT_UI1;
VectorFromBstr(Book->bstrVal,&varbok.parray);
try{
SchedQ->SetBook(COleVariant(varbok));
SchedQ->Delete();
}catch(CDaoException* e){
Book->vt=VT_NULL;
e->Delete();
}
}
// m_gridView和DBGrid空间关联
m_pRS.CreateInstance( __uuidof(Recordset));
CString strConnection( _T("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Data.mdb")); try
{
m_pRS->CursorLocation = adUseClient;
m_pRS->Open(_T("SELECT * FROM Data"), _bstr_t(strConnection), adOpenKeyset,adLockOptimistic, adCmdText);
}
catch (_com_error &e)
{
AfxMessageBox( (LPCTSTR)e.Description());
}
m_gridView.SetRefDataSource(NULL);
m_gridView.SetRefDataSource( (LPUNKNOWN) m_pRS );
m_gridView.Refresh();
DBGrid本身支持数据的修改什么,就像Access一样。
如果你不和数据库关联还是用MSFlexGrid吧
谢谢你的资料和解答。有个问题:MSFlexGrid 好像不支持在网格中编辑吧。
_Recordset rs;
rs.CreateInstance("ADODB.Recordset");
m_grid.SetrefDataSource(NULL);
m_grid.SetrefDataSource(rs);
m_grid.Refresh();
int rows=m_grid.GetRow();结果:rows等于-1;
m_grid.setrow(1);// erroe: recordset invalid.
还是不行啊~是不是要完全用recordset才能在datagrid control中显示数据啊?(太惨了~~~)
有没有简单的方法在网格控件中显示数据和编辑数据啊?
谁能帮忙,谢谢了。