注册 登录
编程论坛 VB6论坛

求助关于vb6 ado adAffectGroup的使用方法

w360989426 发布于 2014-02-04 10:49, 1438 次点击
Private Sub Command7_Click()
If Adodc1.Recordset.EOF = True Then
MsgBox "没有记录可供删除!", vbOKOnly, "温馨提示"
Else
If MsgBox("你真的不需要打印这个订单编号的送货单吗?", vbOKCancel, "温馨提示") = vbOK Then
DataGrid1.AllowDelete = True
Adodc1.Recordset.Filter = "订单编号='" & 订单编号 & "'"
Adodc1.Recordset.Delete adAffectGroup (这行提示出错,提示在此环境中不允许操作)这是为什么??
DataGrid1.AllowDelete = False
MsgBox "删除订单编号成功", vbOKOnly, "温馨提示"

End If
End If
End Sub


求大师指点啊,我快疯掉了。。。。。
我的本意是要删除Adodc1.Recordset.Filter = "订单编号='" & 订单编号 & "'"
但是我不想去直接操作数据库,因为这是为一个打印程序所开发的程序,我只是想让他把查询中不想打印的recordest从adodc1.recordest中删除,
但是我现在遇到这个情况真不知道该如何去解决,还请大师指点啊。。。谢谢了啊
25 回复
#2
w3609894262014-02-04 15:36
怎么没有人回答我的问题啊。。。来人啊,,,,
#3
chen35232014-02-04 17:00
既然是查询,可以用“订单编号<>”来完成查询,然后打印DataGrid1
#4
lowxiong2014-02-04 17:08
我也没有找到好的方法,开始以为是记录集锁定模式(LockType)和记录集打开模式(CursorType)造成的,但尝试各种组合没有解决,但貌似直接delete是可以的,因此用笨法子不知道能否达到你的要求,修改后的代码如下(先备份数据库,因为会真正删除掉数据库符合要求的记录的):
Private Sub Command7_Click()
  If Adodc1.Recordset.EOF = True Then
   MsgBox "没有记录可供删除!", vbOKOnly, "温馨提示"
  Else
    If MsgBox("你真的不需要打印这个订单编号的送货单吗?", vbOKCancel, "温馨提示") = vbOK Then
      DataGrid1.AllowDelete = True
      Adodc1.Recordset.Filter = "订单编号='" & 订单编号 & "'"
      While Not Adodc1.Recordset.EOF
        Adodc1.Recordset.Delete
        Adodc1.Recordset.MoveNext
      Wend
      Adodc1.Recordset.Close
      Adodc1.Recordset.Filter = ""
      Adodc1.Refresh
      DataGrid1.AllowDelete = False
      MsgBox "删除订单编号成功", vbOKOnly, "温馨提示"
    End If
  End If
End Sub



[ 本帖最后由 lowxiong 于 2014-2-4 17:26 编辑 ]
#5
w3609894262014-02-04 19:49
回复 4楼 lowxiong
谢谢版主了,我去试试看,如果不行的话,只能去建一个临时表了。。哎。。。谢谢拉
#6
w3609894262014-02-05 10:31
回复 4楼 lowxiong
Private Sub Command7_Click()
  If Adodc1.Recordset.EOF = True Then
   MsgBox "没有记录可供删除!", vbOKOnly, "温馨提示"
  Else
    If MsgBox("你真的不需要打印这个订单编号的送货单吗?", vbOKCancel, "温馨提示") = vbOK Then
      DataGrid1.AllowDelete = True
      Adodc1.Recordset.Filter = "订单编号='" & 订单编号 & "'"
      While Not Adodc1.Recordset.EOF
        Adodc1.Recordset.Delete  (程序运行到此行出错,提示缺少更新或刷新的键列信息)
        Adodc1.Recordset.MoveNext
      Wend
      Adodc1.Recordset.Close
      Adodc1.Recordset.Filter = ""
      Adodc1.Refresh
      DataGrid1.AllowDelete = False
      MsgBox "删除订单编号成功", vbOKOnly, "温馨提示"
    End If
  End If
End Sub
只有本站会员才能查看附件,请 登录

版主这是什么原因,请指点啊。。。。谢谢啊!!
#7
lowxiong2014-02-05 11:41
未能模拟出你的错误,网上说缺少主键,我也把实验数据库的主键取消了,仍然能正常删除,如果你能把你的程序和数据库打包过来,或许我能找到错误原因。
#8
w3609894262014-02-05 12:11
回复 7楼 lowxiong
版主,请给我一个邮箱,我发过来您帮我看一下,谢谢拉!
#9
lowxiong2014-02-05 12:13
lowxiong@
#10
w3609894262014-02-05 13:52
回复 9楼 lowxiong
版主,邮件给您发了,麻烦您看一下啊,谢谢拉!
#11
lowxiong2014-02-05 16:23
看了你的代码,主要是因为你使用了联合查询的原因导致的,要达到你的目的可用两种方法,代码分别如下(均已调试通过):
一、掩耳盗铃方法:这种方法并不真正删除记录而是把要删除的记录屏蔽掉,但你要改进你的打印代码,你excel是拷贝记录集的,会把已经屏蔽的记录原本拷贝。
Private Sub Command7_Click()
  If Adodc1.Recordset.EOF = True Then
   MsgBox "没有记录可供删除!", vbOKOnly, "温馨提示"
  Else
    If MsgBox("你真的不需要打印【" & Trim(订单编号) & "】这个订单编号的送货单吗?", vbOKCancel, "温馨提示") = vbOK Then
      If Adodc1.Recordset.Filter = 0 Or Adodc1.Recordset.Filter = "" Then
        Adodc1.Recordset.Filter = "订单编号<>'" & Trim(订单编号) & "'"
      Else
        Adodc1.Recordset.Filter = Adodc1.Recordset.Filter & " and 订单编号<>'" & Trim(订单编号) & "'"
      End If
      MsgBox "删除订单编号成功", vbOKOnly, "温馨提示"
    End If
  End If
End Sub

二、分别处理法:这种方法会真正删除出库单记录,打印代码无需更改(把你提供的实验记录都删了,恢复麻烦)
Private Sub Command7_Click()
  Dim con As New ADODB.Connection, a As String
  If Adodc1.Recordset.EOF = True Then
   MsgBox "没有记录可供删除!", vbOKOnly, "温馨提示"
  Else
    If MsgBox("你真的不需要打印【" & Trim(订单编号) & "】这个订单编号的送货单吗?", vbOKCancel, "温馨提示") = vbOK Then
      con.Open Adodc1.ConnectionString
      If con.State <> 1 Then
        MsgBox "数据库连接失败"
        Exit Sub
      End If
      a = "delete 出库单 from 出库单 where 订单编号='" & Trim(订单编号) & "'"
      con.Execute a
      Adodc1.Refresh
      con.Close
      MsgBox "删除订单编号成功", vbOKOnly, "温馨提示"
    End If
  End If
End Sub

#12
w3609894262014-02-05 17:20
回复 11楼 lowxiong
谢谢版主帮了我这么大的忙,实在感谢!!!太谢谢拉!我会选择一种方法来操作的,谢谢诶
#13
w3609894262014-02-05 20:30
回复 11楼 lowxiong
版主,试了你的2种方法我觉得都不怎么适合我,现在我自己想到一种方法,并且已经实施成功,先说来一起分享一下,
1.在sql中建1个临时表,名叫送货单临时表
2.点击查询的时候,自动将所查询的东西写入送货单临时表
3.当点击删除的时候自动获取所要删除的单号
4.用sql语句删除送货单临时表中的信息
5.更新adodc1控件,就可以达到我的目地了
呵呵,还望版主以后多指教
Private Sub Command7_Click() 删除指定编号的源码
列序号 = 0
If Adodc1.Recordset.EOF = True Then
MsgBox "没有记录可供删除!", vbOKOnly, "温馨提示"
Else
If MsgBox("你真的不需要打印这个订单编号的送货单吗?", vbOKCancel, "温馨提示") = vbOK Then
DataGrid1.AllowDelete = True
strSQL = "delete from 送货单临时表 where 订单编号='" & 订单编号 & "'"
cn.Open strCn
              rs.Open strSQL, cn
             cn.Close

DataGrid1.AllowDelete = False
             sql1 = "Select 订单编号,日期,地域,负责人,酒店名称,厨房,货物名称,订货量,出库数量,单价,单位,所属公司 from 送货单临时表 order by 日期,地域,负责人,酒店名称,厨房,排序号,序号"
            Adodc1.RecordSource = sql1
            Adodc1.Refresh
            Call 送货单确定列表框长度
MsgBox "删除订单编号成功", vbOKOnly, "温馨提示"
列序号 = 1
End If
End If
End Sub


Private Sub Command6_Click() 查询的源码
列序号 = 0
strSQL = "delete from 送货单临时表"
             cn.Open strCn
              rs.Open strSQL, cn
             cn.Close

    If Text3.Text = "" Then
        If CheckBox1.Value = True Then
            strSQL = "insert into 送货单临时表(序号,订单编号,日期,地域,负责人,酒店名称,厨房,货物名称,订货量,出库数量,单价,单位,所属公司,排序号) select  出库单.序号,出库单.订单编号,出库单.日期,出库单.地域,出库单.负责人,出库单.酒店名称,出库单.厨房,出库单.货物名称,出库单.订货量,出库单.出库数量,出库单.单价,酒店货品信息表.单位,出库单.所属公司,出库单.排序号 from 出库单,酒店货品信息表 where 出库单.酒店名称=酒店货品信息表.酒店名称 and 出库单.厨房=酒店货品信息表.厨房 and  出库单.货物名称 = 酒店货品信息表.货物品名 and  出库单.酒店名称 like '%" & Text2.Text & "%' And (出库单.日期 between '" & text1.Value & "'and '" & DTPicker1.Value & "')and 出库单.负责人 like '%" & Combo1.Text & "%' and 出库单.地域 like '%" & Combo2 & "%' "
             cn.Open strCn
              rs.Open strSQL, cn
             cn.Close
             sql1 = "Select 订单编号,日期,地域,负责人,酒店名称,厨房,货物名称,订货量,出库数量,单价,单位,所属公司 from 送货单临时表 where 酒店名称 like '%" & Text2.Text & "%' And (日期 between '" & text1.Value & "'and '" & DTPicker1.Value & "')and 负责人 like '%" & Combo1.Text & "%' and 地域 like '%" & Combo2 & "%' order by 日期,地域,负责人,酒店名称,厨房,排序号,序号"
            Adodc1.RecordSource = sql1
            Adodc1.Refresh
            Call 送货单确定列表框长度
        Else
            MsgBox "请选择日期!", vbOKOnly, "错误提示"
            Exit Sub
        End If
    Else
        strSQL = "insert into 送货单临时表(序号,订单编号,日期,地域,负责人,酒店名称,厨房,货物名称,订货量,出库数量,单价,单位,所属公司,排序号) select 出库单.序号,出库单.订单编号,出库单.日期,出库单.地域,出库单.负责人,出库单.酒店名称,出库单.厨房,出库单.货物名称,出库单.订货量,出库单.出库数量,出库单.单价,酒店货品信息表.单位,出库单.所属公司,出库单.排序号 from 出库单,酒店货品信息表 where 出库单.酒店名称=酒店货品信息表.酒店名称 and 出库单.厨房=酒店货品信息表.厨房 and  出库单.货物名称 = 酒店货品信息表.货物品名 and  出库单.订单编号 like '%" & Text3.Text & "%'order by 出库单.日期,出库单.地域,出库单.负责人,出库单.酒店名称,出库单.厨房,出库单.排序号,出库单.序号"
       cn.Open strCn
              rs.Open strSQL, cn
             cn.Close
             sql1 = "Select 订单编号,日期,地域,负责人,酒店名称,厨房,货物名称,订货量,出库数量,单价,单位,所属公司 from 送货单临时表 where 订单编号 like '%" & Text3.Text & "%'order by 日期,地域,负责人,酒店名称,厨房,排序号,序号"
        Adodc1.RecordSource = sql1
        Adodc1.Refresh
        Call 送货单确定列表框长度

    End If
列序号 = 1
End Sub
#14
lowxiong2014-02-05 22:08
没必要这么复杂,不需要建立临时表,通过自动构建sql语句可完成所需功能(不会真的删除出库记录)。代码如下:
Private Sub Command7_Click()
  Dim a As String, s As String, e As String, i As Integer
  If Adodc1.Recordset.EOF = True Then
   MsgBox "没有记录可供删除!", vbOKOnly, "温馨提示"
  Else
    If MsgBox("你真的不需要打印【" & Trim(订单编号) & "】这个订单编号的送货单吗?", vbOKCancel, "温馨提示") = vbOK Then
      订单编号 = Trim(订单编号)
      a = Adodc1.RecordSource
      i = InStr(1, a, " order by")
      s = Left(a, i)
      e = Right(a, Len(a) - i)
      s = s & " and 订单编号<>'" & 订单编号 & "' "
      Adodc1.RecordSource = s & e
      Adodc1.Refresh
    End If
  End If
End Sub
#15
w3609894262014-02-05 22:59
回复 14楼 lowxiong
版主。。。有这么简单的方法为何不早点告知额。。搞的我去建一个临时表,忙了半天额。。。。泪流满面啊!
#16
lowxiong2014-02-06 09:17
必要的重复和做无用功是技术逐步提高的一个过程。
粗略地看了下你的程序,有如下建议:
1、认真规划下你的数据库各表间关系,基础数据表都应有key,减少冗余。比如:你在出库单里,使用了“酒店名称”、“厨房”、“地域”,这是不合理的,因为将来该酒店可能会改名,而“厨房”和“地域”是酒店的属性,不需要出现在出库单里(多厨房和连锁店则也应用唯一编号替代,通过这个唯一编号可反过来找到酒店名称、厨房名称和地域),这3项可归为1项,即“收货方”,应该就是“厨房”的唯一编号。
2、建议你“操作员”表(你的用户表)里的密码用binary类型,至少不会让有一定sql操作能力的人一眼就看的出密码明文。
3、对于sql数据库应用应该在程序里添加注册端口号的代码,虽然sql默认都是1433,但有安全意识的设计人员一般会改通用端口号的,这时就需要客户端有自动注册端口号的功能。不要在程序里使用sa(或sql其他的超级用户登录,应建立独立数据库用户)操作数据库,因为sa也相当于服务器的系统超级用户。
4、不要使用adodc控件,应用引用和代码方式解决,好好规划程序要达到的功能,合理使用全程变量来提高执行效率,多使用函数或过程完成特定功能。建议当程序完成90%的功能时,果断清除所有代码重来,你的程序将会设计的更合理、更有执行效率。
#17
w3609894262014-02-06 11:21
回复 16楼 lowxiong
谢谢版主的建议啊。。。。初来乍到,要学习的东西还很多呵呵。。。谢谢拉!
#18
w3609894262014-02-06 13:00
回复 16楼 lowxiong
select  出库单.订单编号,出库单.日期,出库单.地域,出库单.负责人,出库单.酒店名称,出库单.厨房,出库单.货物名称,出库单.订货量,出库单.出库数量,出库单.单价,酒店货品信息表.单位,出库单.所属公司 from 出库单,酒店货品信息表 where 出库单.酒店名称=酒店货品信息表.酒店名称 and 出库单.厨房=酒店货品信息表.厨房 and  出库单.货物名称 = 酒店货品信息表.货物品名 and  排序号 =(select max(排序号) from 出库单) order by 出库单.地域,出库单.日期,出库单.负责人,出库单.酒店名称,出库单.厨房,出库单.排序号,出库单.序号


版主不好意思,你能帮我看一下,这段sql代码有什么问题吗,在我昨天发给你的那个数据库里却查不出来,不知道为什么,你能帮我看一下吗?谢谢
#19
lowxiong2014-02-06 14:05
你的sql语句标准化后如下:
SELECT 出库单.订单编号, 出库单.日期, 出库单.地域, 出库单.负责人, 出库单.酒店名称,
      出库单.厨房, 出库单.货物名称, 出库单.订货量, 出库单.出库数量, 出库单.单价,
      酒店货品信息表.单位, 出库单.所属公司
FROM 出库单 INNER JOIN
      酒店货品信息表 ON 出库单.酒店名称 = 酒店货品信息表.酒店名称 AND
      出库单.厨房 = 酒店货品信息表.厨房 AND
      出库单.货物名称 = 酒店货品信息表.货物品名
WHERE (出库单.排序号 =
          (SELECT MAX(排序号)
         FROM 出库单))
ORDER BY 出库单.地域, 出库单.日期, 出库单.负责人, 出库单.酒店名称, 出库单.厨房,
      出库单.排序号, 出库单.序号
问题出在红字处,由于你使用的联合查询中的数据没有数据的序号和出库单中最大序号相等,所以没有数据显示。貌似你要取得排序号最大的记录,你只需要按排序号降序排列,取第一条记录即可,sql语句如下(附企业管理器内运行结果图):
SELECT TOP 1 出库单.订单编号, 出库单.日期, 出库单.地域, 出库单.负责人,
      出库单.酒店名称, 出库单.厨房, 出库单.货物名称, 出库单.订货量, 出库单.出库数量,
      出库单.单价, 酒店货品信息表.单位, 出库单.所属公司
FROM 出库单 INNER JOIN
      酒店货品信息表 ON 出库单.酒店名称 = 酒店货品信息表.酒店名称 AND
      出库单.厨房 = 酒店货品信息表.厨房 AND
      出库单.货物名称 = 酒店货品信息表.货物品名
ORDER BY 出库单.排序号 DESC

只有本站会员才能查看附件,请 登录
#20
w3609894262014-02-06 15:09
回复 19楼 lowxiong
但是有点很奇怪啊,这条语句我
只有本站会员才能查看附件,请 登录
在一个和他数据结构完全一样的数据中运行是可以的,如上图,而且昨晚上面那个删除代码,我试了,其他没什么问题,但是有一点哦,如果在窗口初始化的时候,datagrib中有数据,用这删除就会报错,因为昨天的我发给你看了,就是因为上述的sql语句在初始化中没有起到作用,才会导致初始化中datagrid中没有数据,一般情况是有数据的,但以删除就报错。
#21
lowxiong2014-02-06 16:54
这并不奇怪,昨天你实验时d1024610订单的排序号恰好是最大,后来删除了,剩下的排序号最大的不符合联合查询的条件,所以没记录显示,如果你要模拟出有记录,也很简单,在企业管理器中首先运行语句"select * from 出库单 order by 排序号 desc",这时表中第一条记录即是排序号最大的,将它排序号改为0(我这里显示的是d102449,排序号为2070,我把2070改为0),再运行你的语句,这时你就可以看到两条记录了,居然不是同一订单号,见下图:
只有本站会员才能查看附件,请 登录
#22
w3609894262014-02-06 17:44
回复 20楼 w360989426
版主,现在不讨论这个问题,
1.现在问题的关键是你写的那段程序在一种情况下会出错
2.将以下代码替换下,在界面初始化的时候,datagrid中会有数据,你去点击删除的话会报错,请版主试试看
替换代码如下:
Sub 送货单确定时间和初始化控件()
    Text1.Enabled = False
    DTPicker1.Enabled = False
    sql2 = "select  出库单.订单编号,出库单.日期,出库单.地域,出库单.负责人,出库单.酒店名称,出库单.厨房,出库单.货物名称,出库单.订货量,出库单.出库数量,出库单.单价,酒店货品信息表.单位,出库单.所属公司 from 出库单,酒店货品信息表 where 出库单.酒店名称=酒店货品信息表.酒店名称 and 出库单.厨房=酒店货品信息表.厨房 and  出库单.货物名称 = 酒店货品信息表.货物品名 and  出库单.酒店名称 like '%湖州%'order by 出库单.地域,出库单.日期,出库单.负责人,出库单.酒店名称,出库单.厨房,出库单.排序号,出库单.序号"
    Adodc1.RecordSource = sql2
    Adodc1.Refresh
End Sub

#23
w3609894262014-02-06 17:58
回复 9楼 lowxiong
第一张
只有本站会员才能查看附件,请 登录

第二张
只有本站会员才能查看附件,请 登录

第三张
只有本站会员才能查看附件,请 登录


版主:请看上面三张图
第一张为 条件:排序号=‘2070’的查询结果
第二张为 数据库中的截图
第三张为 条件:排序号=‘2060’的查询结果
明显第一张没有结果而第三张有结果
而2070,2060这2个序号都是存在与数据库中的
所有这就让我很疑惑,而2070这个序号正好是select max(排序号) from 出库单的值

#24
lowxiong2014-02-06 18:36
排序号为2070里的货品、厨房在酒店里没有对应信息,所以查询不出来(联合查询联合项必须一一对应才显示查询记录)。
你在22楼里说的情况我检查了下,是因为你在初始化提供的sql语句里的"order by"命令前面没有空格,导致程序判断失误。这段代码是针对你sql语句的特点写的,可适应性不强,比如如果你sql语句没有排序命令,这段代码也会出错。代码修改如下即可解决:
Private Sub Command7_Click()
  Dim a As String, s As String, e As String, i As Integer
  If Adodc1.Recordset.EOF = True Then
   MsgBox "没有记录可供删除!", vbOKOnly, "温馨提示"
  Else
    If MsgBox("你真的不需要打印【" & Trim(订单编号) & "】这个订单编号的送货单吗?", vbOKCancel, "温馨提示") = vbOK Then
      订单编号 = Trim(订单编号)
      a = Adodc1.RecordSource
      i = InStr(1, a, "order by") - 1
      s = Left(a, i)
      e = Right(a, Len(a) - i)
      s = s & " and 订单编号<>'" & 订单编号 & "' "
      Adodc1.RecordSource = s & " " & e
      Adodc1.Refresh
    End If
  End If
End Sub



[ 本帖最后由 lowxiong 于 2014-2-6 18:43 编辑 ]
#25
w3609894262014-02-06 19:04
回复 24楼 lowxiong
哦。。明白了,呵呵谢谢拉。。原来是这样的啊。。不问的话,估计这个问题又要困扰我几个月了,那学习进度就慢的多了,有个高人问一问可能使我少走很多弯路,谢谢拉!再次感谢,希望能与你交个朋友。
#26
w3609894262014-02-07 11:21
回复 23楼 w360989426
版主你好,又有一事请教,请看下面这条sql语句
select  出库单.订单编号,出库单.日期,出库单.地域,出库单.负责人,出库单.酒店名称,出库单.厨房,出库单.货物名称,出库单.订货量,出库单.单价,酒店货品信息表.单位,出库单.备注
 from 出库单 left join 酒店货品信息表 on 出库单.酒店名称=酒店货品信息表.酒店名称 and 出库单.厨房=酒店货品信息表.厨房 and  出库单.货物名称 = 酒店货品信息表.货物品名 and  出库单.酒店名称 like '%" & Text2.Text & "%' And (出库单.日期 between '" & text1.Value & "'and '" & DTPicker1.Value & "')and 出库单.负责人 like '%" & Combo1.Text & "%' and 出库单.地域 like '%" & Combo2 & "%'
order by 出库单.日期,出库单.地域,出库单.负责人,出库单.酒店名称,出库单.厨房,出库单.排序号,出库单.序号

这条语句本身么有错,但有如下问题,例如出库单中有70000条记录,但是象这样联合查询出来可能就会有 72000条记录,
解决方法是:加上 distinct 出库单.序号,就可以使出库单记录数=联合查询记录数,
但这样又有另外一个问题出现,sql语句:order by 出库单.日期,出库单.地域,出库单.负责人,出库单.酒店名称,出库单.厨房,出库单.排序号,出库单.序号
提示出错,原因为order by 中的条件,有的不包含在select distinct的项目中,

请教:该如何2全其美的解决这个问题。即可以加select distint 又可以使order by 后面的条件一个不少,还望版主指点一下!谢谢!
1