Office中国论坛/Access中国论坛

标题: 如何用SQL或其它方法更新表 [打印本页]

作者: 简    时间: 2012-4-7 20:49
标题: 如何用SQL或其它方法更新表
本帖最后由 简 于 2012-4-7 20:52 编辑

我希望把定额表中定额更新在AA表中相对应的品号的定额字段中。

特别强调的是,

同一个产品,在同一台机床,同一天里,如果班次中有两个中班,那么该中班次的定额就取一半,否则就是全额。  
比如,本来A042的定额是2700,它在3月6号 这天,在29号机床上有两个中班,所以中班的定额就为2700/2=1350,而白班和夜班就是2700。  

像B092产品,它在3月8号这天,在21号机床 上只有一个中班,所以它白、中、夜的定额都是1800。

最后的结果如图所示。

[attach]48909[/attach]

[attach]48910[/attach]

作者: todaynew    时间: 2012-4-7 20:59
在定额控件的控件来源中写:
=Dlookup("定额","定额表","条件表达式")/Dcount("*","子窗体数据源的表名称","机床=" & [机床] & " and 日期=#" & [日期] & "# and 班次='" [班次] & "'")
作者: 简    时间: 2012-4-7 21:19
todaynew 发表于 2012-4-7 20:59
在定额控件的控件来源中写:
=Dlookup("定额","定额表","条件表达式")/Dcount("*","子窗体数据源的表名称" ...

我照着写了来,不对呢,AA表中的定额字段值都变成(定额表.定额)/2,而事实上我要求的是,有两个中班的,定额字段才为定额表.定额/2,不知错在哪里了。
作者: todaynew    时间: 2012-4-7 22:03
简 发表于 2012-4-7 21:19
我照着写了来,不对呢,AA表中的定额字段值都变成(定额表.定额)/2,而事实上我要求的是,有两个中班的,定 ...

鬼打架,加个班组的表达式不就完事了嘛。
作者: 简    时间: 2012-4-15 19:28
todaynew 发表于 2012-4-7 22:03
鬼打架,加个班组的表达式不就完事了嘛。

我想再问一下,我想把AA表中相同生产日期,相同产品代号,相同机床,相同班次的记录合为一条记录,完成数量为要合成的记录的完成数量之和,合成后的记录另存为BB表。

请问SQL代码该怎么写呢。
作者: todaynew    时间: 2012-4-15 20:03
简 发表于 2012-4-15 19:28
我想再问一下,我想把AA表中相同生产日期,相同产品代号,相同机床,相同班次的记录合为一条记录,完成数 ...

具体语句不写,方法可以如下:
1、在查询设计视图中先按要求建立一个分组查询,生产日期、机床、班次分组,完成数量合计;
2、查看分组查询是否为所需结果,如果不是则进行相应调整;
3、在分组查询的设计视图中,建立生成查询,生成的表名为BB。如果已经建立了BB则建立追加查询,将分组查询的结果追加到BB表中。
4、将设计视图转入SQL设计视图,拷贝生成查询的SQL语句(或者是追加查询),将其粘贴到VB的代码中去。
作者: aslxt    时间: 2012-4-15 21:18
查询1:
SELECT AA.生产日期, AA.班组, AA.班次, AA.机床, Count(AA.ID) AS ID之计数
FROM AA
GROUP BY AA.生产日期, AA.班组, AA.班次, AA.机床
作者: aslxt    时间: 2012-4-15 21:19
查询2:
SELECT AA.ID, AA.生产日期, AA.产品代号, AA.刀数, 定额表.定额, AA.班组, AA.班次, AA.完成数量, AA.机床
FROM AA INNER JOIN 定额表 ON AA.产品代号 = 定额表.产品代号;

作者: aslxt    时间: 2012-4-15 21:19
本帖最后由 aslxt 于 2012-4-15 21:20 编辑

查询3(结果):
SELECT 查询2.ID, 查询2.生产日期, 查询2.产品代号, 查询2.刀数, [查询2].[定额]/[查询1].[ID之计数] AS 定额值, 查询2.班组, 查询2.班次, 查询2.完成数量, 查询2.机床
FROM 查询2 INNER JOIN 查询1 ON (查询2.机床 = 查询1.机床) AND (查询2.班次 = 查询1.班次) AND (查询2.班组 = 查询1.班组) AND (查询2.生产日期 = 查询1.生产日期)
ORDER BY 查询2.ID;
作者: aslxt    时间: 2012-4-15 21:22
[attach]48988[/attach]
作者: 简    时间: 2012-4-19 21:04
我想请教一下避免记录重复的问题。
以上述附件中的AA表为例,同一天,同一个产品代号,同一台机床,同一个班次,同一个班组,同一个刀数,不允许有相同的完成数量。
比如说,同一天为3月6日,产品代号为A042在29号机床上,A班组的白班,用9刀完成了2400个产品数量,如果再输入3月6号,A042,29号机床,A班组,白班,9刀数,2400,则就重复了。

如何避逸这种情况呢。

我曾经用Dlookup来解决重复记录,但DlookUP的条件项好像最多只能为4项,超过4项条件就无效了。
作者: todaynew    时间: 2012-4-19 21:08
本帖最后由 todaynew 于 2012-4-19 21:13 编辑
简 发表于 2012-4-19 21:04
我想请教一下避免记录重复的问题。
以上述附件中的AA表为例,同一天,同一个产品代号,同一台机床,同一个 ...


办法有若干种,最简单的就是用Dcount或者Dlookup函数确认是否有1条这样的记录存在,如果存在就不做追加操作。

没有听说有条件的项数有什么限制,你写个几十项都没问题,除非你写错球了。{:soso_e120:}

再告诉你一个更为直接而简单的办法,就是将若干字段组合为一个唯一性索引,这是从后台进行根本性的限制。
作者: 简    时间: 2012-4-19 21:17
我还想请教个问题,即在不同子窗体中选中相同机床号的记录。

如附件的主窗体中有白班,中班,夜班三个子窗体,当我在白班子窗体中选中29号机床,则中班和夜班中有29号机床的记录就高亮显示,但子窗体并不筛选。

请问这种效果能实现吗?

[attach]49032[/attach]
作者: todaynew    时间: 2012-4-19 21:22
简 发表于 2012-4-19 21:17
我还想请教个问题,即在不同子窗体中选中相同机床号的记录。

如附件的主窗体中有白班,中班,夜班三个子 ...

好办呀,依据选中值动态设置背景色、或则选中或则条件格式皆可。
作者: 简    时间: 2012-4-19 21:26
todaynew 发表于 2012-4-19 21:08
办法有若干种,最简单的就是用Dcount或者Dlookup函数确认是否有1条这样的记录存在,如果存在就不做追加 ...

我的代码曾这样写:
Dim same1

same1 = DLookup("完成数量", "AA", "[生产日期]+[产品代号]+[班组]+[班次]+[刀数]+[单价]+[完成数量]='" & Me.生产日期 + Me.产品代号 + Me.班组 + Me.班次 + Me.刀数 + Me.单价 + Me.完成数量) & "'")

    If IsNull(same1) = False Then

        strMsg = "记录重复,请重新输入。"
        ……
  endif

注意,我增加了一项[单价]。除了单价是数字类型外,其余都是字符类型。

运行中,不管我是否输入相同记录时,都提示我输入了相同记录,我不知我的上述代码错在哪里呢。

作者: 简    时间: 2012-4-19 21:30
todaynew 发表于 2012-4-19 21:22
好办呀,依据选中值动态设置背景色、或则选中或则条件格式皆可。

你这样说我都知道,但是叫我处理,我就是不知如何处理呀,好汉呀,给个例子让我开开窍,好不好。
作者: todaynew    时间: 2012-4-19 21:33
本帖最后由 todaynew 于 2012-4-19 21:41 编辑
简 发表于 2012-4-19 21:17
我还想请教个问题,即在不同子窗体中选中相同机床号的记录。

如附件的主窗体中有白班,中班,夜班三个子 ...


在白班窗体的成为当前时间中写:
Private Sub Form_Current()
    Dim n As Long
    Dim i As Long
    Dim frm As Form
    On Error Resume Next
    Set frm = Me.Parent.Child2.Form
    n = Me.机床.Value
    For i = 1 To frm.RecordsetClone.RecordCount
        frm.SelTop = i
        If frm.Controls("机床").Value = n Then
            frm.SelWidth = 9
            Exit For
        End If
    Next
End Sub

[attach]49033[/attach]
作者: todaynew    时间: 2012-4-19 21:40
简 发表于 2012-4-19 21:26
我的代码曾这样写:
Dim same1

用Cstr强制转换非文本型字段和控件值后试试
作者: 简    时间: 2012-4-19 21:45
todaynew 发表于 2012-4-19 21:33
在白班窗体的成为当前时间中写:
Private Sub Form_Current()
    Dim n As Long

    Set frm = Me.Parent.Child2.Form

这段代码无法运行,出错。
作者: 简    时间: 2012-4-19 21:50
todaynew 发表于 2012-4-19 21:40
用Cstr强制转换非文本型字段和控件值后试试

我用过Cstr,不起作用。

我曾这样写过:
same1 = DLookup("完成数量", "AA", "[生产日期]+[产品代号]+[班组]+[班次]+[刀数]+[单价]+[完成数量]='" & Me.生产日期 + Me.产品代号 + Me.班组 + Me.班次 + Me.刀数 + Cstr(Me.单价) + Me.完成数量) & "'")

[单价]上曾这样写过,Cstr([单价]),但也不起作用。

实在无辙了。


作者: 简    时间: 2012-4-19 22:00
todaynew 发表于 2012-4-19 21:22
好办呀,依据选中值动态设置背景色、或则选中或则条件格式皆可。

老汉,我要去带孩子了,我还有个问题,即选中列的问题。

也就是说,我在白班子窗体选中任一列,比如完成数量这列,则中班子窗体,夜班子窗体的完成数量这列也选中并高亮显示。

这种效果能实现不。

一共三个问题等待解决,在此先谢了。
作者: todaynew    时间: 2012-4-20 13:03
简 发表于 2012-4-19 21:45
Set frm = Me.Parent.Child2.Form

这段代码无法运行,出错。

窗体加载时子窗体的加载有前后顺序,因此在后面的子窗体未加载完成时会跳出错误,解决的办法是在代码中加一句:On Error Resume Next
具体看修改后的示例
作者: todaynew    时间: 2012-4-20 13:09
简 发表于 2012-4-19 21:50
我用过Cstr,不起作用。

我曾这样写过:

你得到的same1的值是什么?

我想你是后面的对same1的判断用反向了,不信你仔细看看。

在不存在的时候查出存在是本事,在存在时查出不存在是错误。
作者: todaynew    时间: 2012-4-20 13:12
简 发表于 2012-4-19 22:00
老汉,我要去带孩子了,我还有个问题,即选中列的问题。

也就是说,我在白班子窗体选中任一列,比如完 ...

加个if判断就可以了吗
if isnull(me.数量.value)=false then
       前面给你的那些代码写这里
end if
作者: 简    时间: 2012-4-20 23:03
todaynew 发表于 2012-4-20 13:03
窗体加载时子窗体的加载有前后顺序,因此在后面的子窗体未加载完成时会跳出错误,解决的办法是在代码中加 ...

现在又有个问题,
比如说,选中白班子窗体的29号机床记录,中班29号机床有两条记录,我希望这两条记录都高亮显示,而不是只显示29号机床的一条记录。
作者: todaynew    时间: 2012-4-21 08:11
本帖最后由 todaynew 于 2012-4-21 08:13 编辑
简 发表于 2012-4-20 23:03
现在又有个问题,
比如说,选中白班子窗体的29号机床记录,中班29号机床有两条记录,我希望这两条记录都 ...


那就用动态设置条件格式,不过代码比较麻烦。可以用列表框替代子窗体这样处理要简单一些。处理方法参见:http://www.office-cn.net/forum.p ... 9%D0%ED%B9%D6%D2%EC

作者: 简    时间: 2012-4-21 12:25
todaynew 发表于 2012-4-21 08:11
那就用动态设置条件格式,不过代码比较麻烦。可以用列表框替代子窗体这样处理要简单一些。处理方法参见 ...

我觉得列表框也是个好办法,但列表框有个缺陷就是,不能进行条件格式的设置,比如我要求完成数量>3000的数据背景显示红色,<500件背景色为绿色。

另外老汉,我还发现两个问题,
1.我觉得用frm.SelWidth =5似乎不是很合适,因为超过5列就不能高亮反显了。为此我改用DoCmd.RunCommand acCmdSelectRecord。

2.我希望中班,夜班的子窗体也实现白班子窗体的效果,即如果我在中班子窗体中选中29号机床,白班和夜班子窗体中29号机床的记录就高亮显示。

我把代码复制后,我认为由于缺少一个对活动子窗体的判断,所以在运行中,陷入了死循环。请问老汉该怎么处理才能让白班,中班,夜班都实现上述的效果呢。
作者: todaynew    时间: 2012-4-21 14:20
本帖最后由 todaynew 于 2012-4-21 14:50 编辑
简 发表于 2012-4-21 12:25
我觉得列表框也是个好办法,但列表框有个缺陷就是,不能进行条件格式的设置,比如我要求完成数量>3000的数 ...


鬼打架。
在A子窗体写A子窗体的代码,在B子窗体写B子窗体的代码,在C子窗体写C子窗体的代码,光标在哪个子窗体上就做那个子窗体的工作,与谁活谁死有何干系?完全是莫名其妙的问题。

不能简单的复制代码,需要将其中的窗体对象做必要的修改。也可写一个带参数的函数那解决这个问题。

1、在标准模块中写:
Function FindRecord(Myfrm As Form, frm As Form, CtrlName As String)
      '参数:Myfrm--当前子窗体
      '      frm --某个需要查找对应记录的子窗体
      '      CtrlName --某个两子窗体相同的字段名称
      '示例:Call FindRecord(me.Form, Me.Parent.Child2.Form, "机床")

     Dim i As Long
     
     For i = 1 To frm.RecordsetClone.RecordCount
          frm.SelTop = i
          If frm.Controls(CtrlName).Value = Myfrm.Controls(CtrlName).Value Then
              frm.SelWidth = frm.Controls.Count / 2
              Exit For
          End If
      Next

End Function

2、在白班窗体中调用函数
Private Sub Form_Current()
     On Error Resume Next
     Call Call FindRecord(me.Form, Me.Parent.Child2.Form, "机床")
     Call Call FindRecord(me.Form, Me.Parent.Child3.Form, "机床")
End Sub

3、中班子窗体中调用函数
Private Sub Form_Current()
     On Error Resume Next
     Call Call FindRecord(me.Form, Me.Parent.Child1.Form, "机床")
     Call Call FindRecord(me.Form, Me.Parent.Child3.Form, "机床")
End Sub

4、夜班子窗体中调用函数
Private Sub Form_Current()
     On Error Resume Next
     Call Call FindRecord(me.Form, Me.Parent.Child1.Form, "机床")
     Call Call FindRecord(me.Form, Me.Parent.Child2.Form, "机床")
End Sub



作者: todaynew    时间: 2012-4-21 15:42
本帖最后由 todaynew 于 2012-4-21 16:35 编辑
简 发表于 2012-4-21 12:25
我觉得列表框也是个好办法,但列表框有个缺陷就是,不能进行条件格式的设置,比如我要求完成数量>3000的数 ...


关于用条件格式解决此问题的方法请参见:http://www.office-cn.net/thread-111494-1-1.html




欢迎光临 Office中国论坛/Access中国论坛 (http://www.office-cn.net/) Powered by Discuz! X3.3