2013年9月11日星期三

delphi中 dataset容易出错的地方 - 涡阳--关羽

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
delphi中 dataset容易出错的地方 - 涡阳--关羽  阅读原文»

最近写delphi项目,用到的数据集中的dataset,一直修改exception啊,写下过程。

在对数据集进行任何操作之前,首先要打开数据集。要打开数据集,可以把Active属性设为True,例如:
  CustTable.Active := True;
  也可以调用Open函数,例如:CustQuery.Open;
  要关闭数据集,可以把Active属性设为False或者调用Close函数。

其次 如果有exception的话,就要判断state,下面我列举下state的值(这样是我从网上找的)

State属性是只读的,下面列出了State属性可能的值:
.dsInactive 数据集已关闭,不能访问它的数据;
.dsBrowse 数据集已打开,可以浏览数据但不能修改数据;
.dsEdit 此时为编辑状态,可以修改数据;
.dsInsert 此时可以插入一条新的记录;
.dsSetKey 只适用于TTableTClientDataSet,此时可以设置范围和键值,并且可以调用GotoKey函数;
.dsCalcFields 正在处理OnCalcFields事件(当字段需要指定一个值的时候促发的事件),此时不能修改非计算字段的值;
.dsCurValue 内部使用;
.dsNewValue 内部使用;
.dsOldValue 内部使用;
.dsFilter 正在进行过滤操作。

当我看到我的项目的state为 dsInactive ,被踢我有多高行啦,然后立马改为dsedit,尼玛。但是还不管用,然后又看到方法:

如果应用程序要修改数据集的数据,必须首先进入dsEdit状态。要进入dsEdit状态,可以调用Edit。不过,调用Edit并不能保证一定能进入dsEdit状态,这还取决于CanModify属性的值。如果这个属性返回True的话,表示数据集是可以读和写的。

终于完成了,尼玛,就因为这被经理说,效率慢,该错误还是比较容易的,但是exception,就不是那么简单。下面补充下dataset的其他state的介绍:

下面的功能我是没用到的::

6.7.2 插入新的记录
  要在数据集中插入新的记录,首先要进入dsInsert状态。要进入dsInsert状态,可以调用InsertAppend函数。不过,调用InsertAppend不一定会使数据集进入dsInsert状态,还取决于CanModify属性的值。
  一旦进入了dsInsert状态,用户就可以在数据控件(一般是TDBGrid)中插入一条新的记录,并给这条记录输入数据。
  如果要通过编程来插入新的记录,就要注意InsertAppend的区别。Insert将把一条新的记录插入到当前记录的前面,而Append将把一条新的记录添加到数据集的末尾。
  插入了新的记录后,应当调用Post或在CachedUpdates属性设为True的情况下调用ApplyUpdates把新的记录写到数据集中。
  如果数据集是已建立了索引的ParadoxdBASE表,新记录将自动移到恰当的位置。
  如果数据集没有建立索引,新记录就插入到数据集的当前位置(Insert)或末尾(Append)
6.7.3 删除记录
  调用Delete函数将删除当前记录,并且使数据集回到dsBrowse状态。如果窗体上有TDBNavigator构件的话,用户可以单击导航器上的“Delete”按钮删除当前记录。当前记录被删除后,下一条记录就成为当前记录。
  如果删除的本来就是最后一条记录,则前一条记录成为当前记录。
6.7.4 修改整条记录
  除了TDBGridTDBNavigator外,大部分数据控件只能工作于数据集的一个或几个字段,而不是整条记录。
  不过,TDataSet提供了若干个方法可以直接修改整条记录而不是单独的字段,这些方法包括:
.AppendRecord类似于Append,但可以给字段赋值,不需要调用Post;
.InsertRecord类似于Insert,但可以给字段赋值,不需要调用Post;
.SetFields对当前记录的字段赋值,需要显式地调用Post
  上述三个方法都要传递一个TVarRec类型的数组作为参数,该数组的每一个元素对应着一个字段的值。如果数组的元素个数小于数据集的字段个数,剩下字段的值就是NULL
  对于没有建立索引的数据集来说,AppendRecord把一条新的记录加到数据集的末尾。对于已建立索引的数据集来说,新记录将自动移到一个恰当的位置。
  SetFields用于对当前记录的字段赋值。在调用SetFields之前,首先要调用Edit,使数据集进入dsEdit状态。调用了SetFields后,需要显式地调用Post函数。
  调用SetFields时,如果您只想对部分字段赋值,让其他字段的值保持不变,可以用NULLNIL

引用其他头文件时出现这种错误,莫名其妙,error C2065: "ColorMatrix": 未声明的标识符 - slq0378  阅读原文»

今天做项目时,直接拷贝了另一个工程里的头文件和源文件,然后运行时就出现这种问题,莫名其妙,在原程序里运行一点问题就没有,但是在新工程里就是error。

1 1>e:\c++\button_fly2\button_fly2\gdipbutton.cpp(216): error C2065: “ColorMatrix”: 未声明的标识符
2 1>e:\c++\button_fly2\button_fly2\gdipbutton.cpp(216): error C2146: 语法错误: 缺少“;”(在标识符“HotMat”的前面)
3 1>e:\c++\button_fly2\button_fly2\gdipbutton.cpp(216): error C2065: “HotMat”: 未声明的标识符
4 1>e:\c++\button_fly2\button_fly2\gdipbutton.cpp(216): error C2059: 语法错误:“{”
5 1>e:\c++\button_fly2\button_fly2\gdipbutton.cpp(216): error C2143: 语法错误 : 缺少“;”(在“{”的前面)
6 1>e:\c++\button_fly2\button_fly2\gdipbutton.cpp(220): error C2143: 语法错误 : 缺少“;”(在“}”的前面)
7 1>e:\c++\button_fly2\button_fly2\gdipbutton.cpp(222): error C2065: “ImageAttributes”: 未声明的标识符
8 1>e:\c++\button_fly2\button_fly2\gdipbutton.cpp(222): error C2146: 语法错误: 缺少“;”(在标识符“ia”的前面)
9 1>e:\c++\button_fly2\button_fly2\gdipbutton.cpp(222): error C2065: “ia”: 未声明的标识符

  同一台机器出现了这样的错误,真是让人费解,然后检查配置环境,结果是两个工程项目属性是一样的,然后检查头文件引用吧,只能一个一个看了,看来半天才发现原来是#include "stdafx.h"的问题,在这里面包含的有其他头文件,所以运行时老是报错。我的程序里添加的有几行代码如下:

#include <gdiplus.h>
#pragma comment(lib, "gdiplus.lib")
using namespace Gdiplus;

  原来是使用了gdi的头文件,这是windows的api,可以预编译,提高速度。

  这里介绍一下stdafx.h是指编译器头文件预编译,所谓头文件预编译,就是把一个工程(Project)中使用的一些MFC标准头文件(如Windows.H、Afxwin.H)预先编译,以后该工程编译时,不再编译这部分头文件,仅仅使用预编译的结果。这样可以加快编译速度,节省时间。

  预编译文件的作用是把工程中的一部分代码提前编译好放在一个.pch文件中,以后在编译其他文件时,如果包含了这个头文件,编译器会首先读取这个.pch文件的内容,从而跳过该头文件的编译,节约了工程的编译时间,而*.pch文件一般是非常的大,因此在工程编译成功后,你可以考虑删除它。

  编译器认为,所有在指令#include "stdafx.h"前的代码都是预编译的,它跳过#include "stdafx. h"指令,使用projectname.pch编译这条指令之后的所有代码。如下是stdafx中常包含的头文件,都是windows的一些核心组件

1 #include <afxwin.h> // MFC 核心组件和标准组件
2 #include <afxext.h> // MFC 扩展
3
4 #include <afxdisp.h> // MFC 自动化类
5
6 #ifndef _AFX_NO_OLE_SUPPORT
7 #include <afxdtctl.h> // MFC 对 Internet Explorer 4 公共控件的支持
8

没有评论:

发表评论