特定条件下的总和数量和价格

时间:2017-07-29 14:09:30

标签: sql vb6 sql-server-2000

我想在excel文件中做一个价格和数量的总和,并将它们存储在数据库表中。所以这是(自己尝试学习) - 假设,这些是excel文件数据:

ProductId - Invoice No - Invoice Date - Price - Quantity
101 - Inv-1000 - 7/10/2017 10:00 - 1000 - 10
101 - Inv-1000 - 7/10/2017 10:30 - 200 - 2 
101 - Inv-1000 - 7/10/2017 10:30 - 400 - 4 'These should be merged with the above one as they have the same invoice, product id and date time
102 - Inv-1000 - 7/10/2017 10:30 - 400 - 20
101 - Inv-1001 - 7/11/2017 10:30 - 300 - 5
102 - Inv-1001 - 7/11/2017 10:30 - 200 - 5

我的要求是,如果有任何产品ID具有相同的发票和发票日期时间,那么它应该合并这些结果,并且数据库表中的输出将如下:

ProductId - Invoice No - Invoice Date - Price - Quantity - Auto No
101 - Inv-1000 - 7/10/2017 10:00 - 1000 - 10 - 1
101 - Inv-1000 - 7/10/2017 10:30 - 600 - 6 - 2 'Finally merged
102 - Inv-1000 - 7/10/2017 10:30 - 400 - 20 - 1
101 - Inv-1001 - 7/11/2017 10:30 - 300 - 5 - 1
102 - Inv-1001 - 7/11/2017 10:30 - 200 - 5 - 1

所以我尝试使用以下代码验证sql查询中的发票号,产品ID和发票日期时间:

str = "SELECT IIF(SUM([Price]) IS NULL, 0, SUM([Price])) AS SumPrice, IIF(SUM([Quantity]) IS NULL, 0, SUM([Quantity])) AS SumQuantity FROM [" & strSheet & "$]" & _
      " WHERE [Invoice No] = '" + InvNo + "'" & _
      " AND [ProductId] = '" + ProductId+ "'" & _
      " AND [Invoice Date] = '" + strDate + "'"

Set rs = con.Execute(str)

但在WHERE子句中,我收到了这些错误 - 标准表达式中的数据类型不匹配

在错误消息之后,我确实只使用了带有产品ID的发票号来检查它是否有效并且确实如此(对于发票'Inv-1000'和产品ID 101),这样但其余的excel数据都不是'装了 -

Excel数据:

ProductId - Invoice No - Invoice Date - Price - Quantity
101 - Inv-1000 - 7/10/2017 10:00 - 1000 - 10
101 - Inv-1000 - 7/10/2017 10:30 - 200 - 2 
101 - Inv-1000 - 7/10/2017 10:30 - 400 - 4 
102 - Inv-1000 - 7/10/2017 10:30 - 400 - 20
101 - Inv-1001 - 7/11/2017 10:30 - 300 - 5
102 - Inv-1001 - 7/11/2017 10:30 - 200 - 5

数据库表中的输出:

ProductId - Invoice No - Invoice Date - Price - Quantity - Auto No
101 - Inv-1000 - 7/10/2017 10:00 - 1600 - 16 - 1

注意:还有一件事,如果总和已经完成,我再次要检查或验证不应该为特定发票号,产品ID和发票日期输入两次总和(我已经在示例项目中完成了验证,但总结一下,验证是否有效?)。

这是完整的代码(使用TextBox并将excel文件保存在D目录中,最后在TextBox中写入--D:\ SampleExcel.xlsx):

Dim recordCount As Integer 'Variable to get record count
Dim i As Integer

Private Sub btnUpload_Click()
   LoadExcelSheet
End Sub

'**Method To Upload Excel File - Starts**
Public Sub LoadExcelSheet()
Dim con As ADODB.Connection
Dim conn As ADODB.Connection

'**Record Set To Check Table Records - Starts**
Dim rs As ADODB.Recordset
Dim rs2 As ADODB.Recordset
Dim rs3 As ADODB.Recordset
'**Record Set To Check Table Records - Ends**

Dim i As Long

Dim strQuery As String
Dim str As String
Dim str2 As String
Dim strQuery2 As String
Dim strQuery3 As String

Dim strFile As String
Dim strSheet As String


Set con = New ADODB.Connection
Set conn = New ADODB.Connection

Set rs = New ADODB.Recordset
Set rs2 = New ADODB.Recordset
Set rs3 = New ADODB.Recordset

i = 0

strFile = txtFileName.Text
strSheet = "Sheet1"
con.Provider = "Microsoft.ACE.OLEDB.12.0"
con.ConnectionString = "Data Source = " & strFile & ";" & "Extended Properties = Excel 12.0;"

conn.Open "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Demo;Data Source=.;"
con.Open

strQuery = "SELECT * FROM [" & strSheet & "$]"
strQuery2 = "SELECT ProductId, [Invoice No], [Invoice Date] FROM DataExcel"
strQuery3 = "SELECT ProductId, [Invoice No], [Invoice Date], [Price], [Quantity] FROM DataExcel"

rs.Open strQuery, con, adOpenStatic, adLockOptimistic
rs2.Open strQuery2, conn, adOpenStatic, adLockOptimistic
rs3.Open strQuery3, conn, adOpenStatic, adLockOptimistic

strDate = Format(Now, "YYYY-MM-DD") + " 00:00:00"

If (rs2.recordCount > 1) Then
  MsgBox "Few or all records already exist! Check excel file."
ElseIf (rs.Fields(0).Name <> rs3.Fields(0).Name Or rs.Fields(1).Name <> rs3.Fields(1).Name Or rs.Fields(2).Name <> rs3.Fields(2).Name Or rs.Fields(3).Name <> rs3.Fields(3).Name Or rs.Fields(4).Name <> rs3.Fields(4).Name) Then
  MsgBox "Column names don't match! Please check excel file."
Else
    Do Until rs.EOF
    Dim InvNo As String
    InvNo = rs.Fields(1).Value

    Dim AutoNo As String
    Dim AutoNo2 As Integer

    Dim ProductId As String
    ProductId = rs.Fields(0).Value

    Dim ProductId2 As Integer
    ProductId2 = rs.Fields(0).Value

    Dim InvoiceDate As String
    InvoiceDate = Trim(rs.Fields(2).Value)

    Dim Price As String
    Price = Trim(rs.Fields(3).Value)

    Dim Quantity As String
    Quantity = Trim(rs.Fields(4).Value)

    strDate = Format(InvoiceDate, "YYYY/MM/DD hh:mm:ss")

    'This is what I am doing - Checking the same invoice no, product id and invoice date.
    'If any found in the excel file, then sum up the quantity and price
    str = "SELECT IIF(SUM([Price]) IS NULL, 0, SUM([Price])) AS SumPrice, IIF(SUM([Quantity]) IS NULL, 0, SUM([Quantity])) AS SumQuantity FROM [" & strSheet & "$]" & _
          " WHERE [Invoice No] = '" + InvNo + "'" & _
          " AND [ProductId] = 101" & _
          " AND [Invoice Date] = '" + strDate + "'"

    Set rs = con.Execute(str)

    Quantity = rs.Fields("SumQuantity").Value
    Price = rs.Fields("SumPrice").Value

    'Here is the trick - Initially passed the excel file data to verify
    'and checking if any product id exists with the same invoice number in the database table
    str = "SELECT ISNULL(MAX([Auto No]),0) AS AutoNo FROM DataExcel" & _
          " WHERE [Invoice No] = '" + InvNo + "'" & _
          " AND [ProductId] = '" + ProductId + "'"

    Set rs2 = conn.Execute(str) 'Gets the auto number

    AutoNo2 = rs2.Fields("AutoNo").Value + 1 'Increments the number by one if any duplicate exists
    AutoNo = AutoNo2 & ""

    str = "INSERT INTO DataExcel (" & _
          "[ProductId], " & _
          "[Invoice No], " & _
          "[Invoice Date], " & _
          "Price, " & _
          "Quantity, " & _
          "[Auto No]" & _
          ") VALUES (" & _
          "'" + ProductId + "'," & _
          "'" + InvNo + "'," & _
          "'" + InvoiceDate + "'," & _
          "'" + Trim(Price) + "'," & _
          "'" + Trim(Quantity) + "'," & _
          "'" + AutoNo + "')"
    conn.Execute (str) 'Finally stores data with tracking or serial numbers

  rs.MoveNext
Loop
End If

rs.Close

Set rs = Nothing

con.Close
conn.Close

Set con = Nothing
Set conn = Nothing
End Sub
'**Method To Upload Excel File - Ends**

2 个答案:

答案 0 :(得分:2)

TBH,我没有尝试运行您的查询,所以我无法对您的错误说些什么。但是,这个查询在这里:

    public void SendMediaTweetReply(string Reply, long StatusId, string ImagePath)
    {
        if (File.Exists(ImagePath))
        {
            using (var stream = new FileStream(ImagePath, FileMode.Open))
            {
                var Media = Service.UploadMedia(new UploadMediaOptions() { Media = new MediaFile() { FileName = ImagePath, Content = stream } });

                List<string> MediaIds = new List<string>();
                MediaIds.Add(Media.Media_Id);

                var Result = Service.SendTweet(new SendTweetOptions() { Status = Reply, InReplyToStatusId = StatusId, MediaIds = MediaIds });
            }
        }
    }

将产生以下行:

strQuery = "SELECT [Invoice No],[invoice Date],[ProductId],"
strQuery += "SUM(Price) AS Price,SUM(Quantity) as Quantity"
strQuery += " FROM [" & strSheet & "$]"
strQuery += " GROUP BY [Invoice No],[invoice Date],[ProductId]"

所以,你可以迭代这些行来导入你的发票。

关于已导入数据的检查:

检查应该像以前一样,你可以跳过两次导入相同的数据,只需使用相同的查询进行检查 - 因为我们按照唯一的发票日期进行分组,同时也授予整个分组的唯一性

恕我直言,我相信,使用这种分组的唯一区别是,您还需要检查Excel文件中的数量总和是否与导入表中已存在的数量之和相同。然后,您可以决定使用新值更新数量总和,跳过导入或引发错误。

答案 1 :(得分:1)

尝试创建获取条件并计算结果的sql函数。 SQL函数是为不同类型的输出提供动态结果的最佳方法。

相关问题