学习请教、WINCC与SQL数据交换

目前数据库内已有大量数据,需把编号相同的但其他数据不同的 N行数据;提取出来写进WINCC MSHFlexGrid控件里,请问对SQL的查询脚本和查询按钮的VB脚本该怎样写,最好带有时间范围筛选。

基于GPT和Monster组的调写:
确定您使用的数据库类型。下面以使用 SQL Server 为例:

SQL 查询脚本:

SELECT DISTINCT id, field1, field2, ..., fieldN
FROM table_name
WHERE date BETWEEN start_date AND end_date
GROUP BY id, field1, field2, ..., fieldN
HAVING COUNT(*) = 1


VB 查询按钮脚本:

Private Sub QueryButton_Click()
    Dim conn As New ADODB.Connection
    Dim rs As New ADODB.Recordset
    Dim strSQL As String

    strSQL = "SELECT DISTINCT id, field1, field2, ..., fieldN " & _
             "FROM table_name " & _
             "WHERE date BETWEEN #" & startDate & "# AND #" & endDate & "# " & _
             "GROUP BY id, field1, field2, ..., fieldN " & _
             "HAVING COUNT(*) = 1"

    conn.Open "Provider=SQLOLEDB;Data Source=yourServerName;Initial Catalog=yourDBName;User ID=yourUsername;Password=yourPassword;"
    rs.Open strSQL, conn

    ' 将查询结果写入 MSHFlexGrid 控件
    With MSHFlexGrid
        .Clear
        .Columns = rs.Fields.Count
        .Rows = 1

        For i = 0 To rs.Fields.Count - 1
            .TextMatrix(0, i) = rs.Fields(i).Name
        Next

        .Rows = .Rows + 1
        .TextMatrix(1, 0) = rs(0).Value
        .TextMatrix(1, 1) = rs(1).Value
        ...
        .TextMatrix(1, N) = rs(N).Value
        rs.MoveNext

        While Not rs.EOF
            .Rows = .Rows + 1
            .TextMatrix(.Rows - 1, 0) = rs(0).Value
            .TextMatrix(.Rows - 1, 1) = rs(1).Value
            ...
            .TextMatrix(.Rows - 1, N) = rs(N).Value
            rs.MoveNext
        Wend
    End With

    rs.Close
    conn.Close
End Sub


该回答引用ChatGPT

首先,关于 SQL 的查询脚本,如果你想查询编号相同的数据,并且按照时间范围进行筛选,可以使用下面的 SQL 语句:

SELECT *
FROM table_name
WHERE code = 'your code' AND time BETWEEN 'start_time' AND 'end_time'
GROUP BY code
HAVING COUNT(*) > 1

其中,table_name是表名,code是编号列的列名,time是时间列的列名,start_time和end_time分别是开始时间和结束时间,请根据实际情况自行修改。

关于 VB 的查询按钮脚本,可以使用 ADO 或者 DAO 等数据访问方式,以下是一个使用 ADO 的示例:

Private Sub Command1_Click()
Dim conn As New ADODB.Connection
Dim rs As New ADODB.Recordset

conn.Open "Provider=SQLOLEDB;Data Source=your_server;Initial Catalog=your_database;User ID=your_username;Password=your_password;"

rs.Open "SELECT * FROM table_name WHERE code = 'your code' AND time BETWEEN 'start_time' AND 'end_time' GROUP BY code HAVING COUNT(*) > 1", conn, adOpenStatic, adLockReadOnly

MSHFlexGrid1.Clear
MSHFlexGrid1.Cols = rs.Fields.Count
MSHFlexGrid1.Rows = 1

For i = 0 To rs.Fields.Count - 1
    MSHFlexGrid1.Col = i
    MSHFlexGrid1.Text = rs.Fields(i).Name
Next

MSHFlexGrid1.Rows = 2

Do While Not rs.EOF
    For i = 0 To rs.Fields.Count - 1
        MSHFlexGrid1.Col = i
        MSHFlexGrid1.Row = MSHFlexGrid1.Rows - 1
        MSHFlexGrid1.Text = rs.Fields(i).Value
    Next
    MSHFlexGrid1.Rows = MSHFlexGrid1.Rows + 1
    rs.MoveNext
Loop

rs.Close
conn.Close
End Sub


SELECT * FROM TableName WHERE ID IN (SELECT DISTINCT ID FROM TableName WHERE Date BETWEEN StartDate AND EndDate);
VB脚本应该是:Dim conn As New ADODB.Connection conn.Open "Provider=SQLOLEDB;Data Source=ServerName;Initial Catalog=DBName;User Id=UserName;Password=Password" Dim rs As New ADODB.Recordset rs.Open "SELECT * FROM TableName WHERE ID IN (SELECT DISTINCT ID FROM TableName WHERE Date BETWEEN '" & StartDate & "' AND '" & EndDate & "')", conn, adOpenStatic, adLockOptimistic MSHFlexGrid1.DataSource = rs MSHFlexGrid1.Refresh.

你需要用 SQL 查询语句从数据库中选择出编号相同且其他数据不同的 N 行数据。下面是一个示例的 SQL 查询语句,该语句查询编号为 X 的数据,并限制时间范围为从 “start_time” 到 “end_time”:

SELECT * FROM table_name
WHERE id = X
AND time BETWEEN 'start_time' AND 'end_time'
GROUP BY id
HAVING COUNT(*) > 1;


对于查询按钮的 VB 脚本,你可以这样写:

Private Sub btnQuery_Click()
    Dim con As New ADODB.Connection
    Dim rs As New ADODB.Recordset
    Dim start_time As Date, end_time As Date

    ' 设置连接字符串,这里以 SQL Server 为例
    con.Open "Driver={SQL Server};Server=.\SQLExpress;Database=test;Trusted_Connection=yes;"

    ' 设置时间范围
    start_time = CDate(Me.txtStartTime.Text)
    end_time = CDate(Me.txtEndTime.Text)

    ' 执行 SQL 查询语句
    rs.Open "SELECT * FROM table_name WHERE id = X AND time BETWEEN '" & start_time & "' AND '" & end_time & "' GROUP BY id HAVING COUNT(*) > 1;", con

    ' 将查询结果写入 WINCC MSHFlexGrid 控件
    Me.MSHFlexGrid1.Clear
    Me.MSHFlexGrid1.Rows = 1
    While Not rs.EOF
        Me.MSHFlexGrid1.Rows = Me.MSHFlexGrid1.Rows + 1
        For i = 0 To rs.Fields.Count - 1
            Me.MSHFlexGrid1.TextMatrix(Me.MSHFlexGrid1.Rows - 2, i) = rs.Fields(i).Value
        Next i
        rs.MoveNext
    Wend

    ' 关闭数据库连接
    rs.Close
    con.Close
End Sub


请注意,上面的代码仅供参考,请根据你的数据库连接情况和实际需求

作者根据资料编写的程序已经可已根据AD查询数据,但我对查出来的数据进行时间段限制,应该怎么修改,我SQL里的记录的时间列名为 时间

'---------------------打开数据库 --------------------'
 sCon= "Provider=SQLOLEDB; Integrated Security =SSPI;Persist Security Info=False; Initial Catalog=生产统计; Data Source=ZKCD\WINCC"
        Set conn=CreateObject("ADODB.Connection")
          conn.ConnectionString = sCon
          conn.CursorLocation = 3  
          conn.Open
        Set oRs1 = CreateObject("ADODB.Recordset")
        Set oCom = CreateObject("ADODB.Command")
         oCom.CommandType = 1

'---------------------查询数据库 --------------------'
strSQL1= "SELECT *  FROM  [当日生产统计]"
strSQL1 = strSQL1 & " WHERE AD = '" & DATE1 & "'"
Set oCom.ActiveConnection = conn
oCom.CommandText = strSQL1           
Set oRs1 = oCom.Execute

SQL查询脚本:

SELECT * FROM TableName WHERE ID in (Select ID From TableName Group by ID HAVING count(*) > 1) AND date BETWEEN dateFrom and dateTo;

VB脚本:

Sub Query_Click()
    Dim strSQL As String
    strSQL = "SELECT * FROM TableName WHERE ID in (Select ID From TableName Group by ID HAVING count(*) > 1) And date BETWEEN '"& dateFrom & "' And '" & dateTo & "'"
    MSHFlexGrid.DataSource = strSQL
    MSHFlexGrid.Refresh
End Sub

https://wenku.baidu.com/view/f908ddd87f1cfad6195f312b3169a4517623e55e.html?_wkts_=1676377569542&bdQuery=WINCC%E4%B8%8ESQL%E6%95%B0%E6%8D%AE%E4%BA%A4%E6%8D%A2