对具有相同产品ID和发票

时间:2017-07-23 08:17:55

标签: sql-server vb6 sql-server-2000

我想做一件简单的事情让我先说清楚。我有一个excel文件,它被一个应用程序加载,用于将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
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

在excel表中,产品ID 101有两个具有相同发票号的条目,具有不同的时间和数量。我想要的是在有类似的发票号和产品ID(重复发票号和产品ID)时创建跟踪号。假设,对于产品ID 101,它已经有两个发票没有'Inv-1000'的条目。因此,它应该在数据库表中创建两个不同的跟踪,如下所示,如下所示:

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 - 200 - 2 - 2
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

我尝试使用以下代码执行上述任务,但即使对于重复的条目,它也只为所有条目创建1:

Do Until rs3.EOF
  If (rs4.recordCount > 0) Then
     generateId = rs3.Fields.Item("Auto No") + 1
  Else
     generateId = 1
  End If           
rs3.MoveNext
Loop

好像我错过了什么。在这方面,任何想法或建议都将受到赞赏。感谢。

注意:我现在正在验证列名称意味着如果excel表列与表列不匹配,则不允许上载数据。同样,我试图验证excel表的行数据。在这种情况下,如果产品ID 101,发票没有'Inv-1000'已经在表中,即使已经存在不同的跟踪,如1,2已经存在,那么它不应该允许进一步上载该数据。它看起来很简单,但没有开始工作。挣扎!样本 - 存在于表格中:

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 - 200 - 2 - 2
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

最后不允许在下次上传上述数据。还有一件事,将文件保存在D目录和TextBox中,写下来上传excel文件 - 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
Dim rs4 As ADODB.Recordset
'**Record Set To Check Table Records - Ends**

Dim i As Long

Dim strQuery As String
Dim strQueryExistData As String
Dim strQueryMatchCol As String
Dim strQueryExcel 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
Set rs4 = 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;Persist Security Info=False;Initial Catalog=Northwind;Data Source=.;"

con.Open

strQuery = "SELECT * FROM [" & strSheet & "$]"
strQueryMatchCol = "SELECT m.[ProductId], m.[Invoice No], m.[Invoice Date], m.[Price], m.[Quantity]  FROM ExcelData m"
strQueryExistData = "SELECT m.[ProductId], m.[Invoice No], m.[Auto No] FROM ExcelData m"
strQueryExcel = "SELECT [ProductId], [Invoice No] FROM [" & strSheet & "$]"

rs.Open strQuery, con, adOpenStatic, adLockOptimistic
rs2.Open strQueryMatchCol, conn, adOpenStatic, adLockOptimistic
rs3.Open strQueryExistData, conn, adOpenStatic, adLockOptimistic
rs4.Open strQueryExcel, con, adOpenStatic, adLockOptimistic

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

  Do Until rs.EOF

  Dim poNo As String
  Dim itemCode As String
  Dim grnNo As String
  Dim matDes As String
  Dim transName As String
  Dim goDown As String
  Dim vendorName As String
  Dim process As String
  Dim vendorDnNo As String
  Dim rcvQty As String
  Dim unit As String
  Dim totalAmt As String
  Dim invoiceNo As String
  Dim generateId As Integer

  generateId = 1

  '**Check Excel Column - Validation**
  If (rs.Fields(0).Name = rs2.Fields(0).Name And rs.Fields(1).Name = rs2.Fields(1).Name And rs.Fields(2).Name = rs2.Fields(2).Name And rs.Fields(3).Name = rs2.Fields(3).Name And rs.Fields(4).Name = rs2.Fields(4).Name And rs.Fields(0).Name <> "") Then

  '**Trying To Check If Product Has The Same Id and Invoice No, Then Increment By One Or Just One**
  '**Example - If Product Id 101 and Invoice No Inv-1000 Has Two Entries (Repeated), Then In The [Auto No] Column
  'Should Be Included With The Numbers 1 and 2**
  Do Until rs3.EOF
  If (rs4.recordCount > 0) Then
    generateId = rs3.Fields.Item("Auto No") + 1
  Else
    generateId = 1
  End If

  rs3.MoveNext
  Loop

  conn.Execute ("INSERT INTO ExcelData ([ProductId], [Invoice No], [Invoice Date], [Price], [Quantity], [Auto No]) VALUES ('" + Trim(rs.Fields(0).Value) + "', '" + Trim(rs.Fields(1).Value) + "', '" + Trim(rs.Fields(2).Value) + "', '" + Trim(rs.Fields(3).Value) + "', '" + Trim(rs.Fields(4).Value) + "', '" + Trim(generateId) + "')")

    i = 1

  Else

    i = 0

  End If

  rs.MoveNext

  Loop

  If (i = 0) Then
     MsgBox "Column names aren't in correct order! Please check excel sheet 1.", vbInformation, "Info"
  ElseIf (i = 1) Then
     MsgBox "Uploaded!", vbInformation, "Info"
  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**

使用上面的代码,现在只获得以下输出:

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 - 200 - 2 - 1
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

1 个答案:

答案 0 :(得分:1)

您应该刷新rs3记录集的内容,以获取当前数据,从而获取更新的记录数,否则您在打开记录时将始终拥有数据。

当您使用模块级变量来存储记录数时,然后在循环内,conn.Execute ("INSERT INTO....之后您只需使用:rs3.requery。这与您在INSERT INTO语句之前关闭并重新打开rs3记录集在某种程度上相同。

修改

此外,您的代码段Do Until rs3.EOF...在我看来应该被这样的查询替换:SELECT ISNULL(MAX([Auto No]),0) FROM ExcelData WHERE [Invoice No]= 'Inv-1000' AND YEAR([Invoice Date]) = 2017。你应该增加那个结果。请注意如何比较日期,对于此选择查询,请删除时间部分。您将在rs3.fields("Auto No")中找到结果。这里不需要循环记录。每次插入后都应该重新查询此记录集。

<强> EDIT2: 这是一个未经测试的伪代码片段,你应该明白这个想法:

fmtString = "YYYY-MM-DD hh:mm:ss" ' you should adapt this to your need '
rs.Open "SELECT * FROM [" & strSheet & "$]", con, adOpenForwardOnly
Do Until rs.EOF
  InvNo = Trim(rs.Fields("InvoiceNo").Value)
  InvDateTime = CDate(rs.Fields("Invoice Date").Value)
  ' separate year from full datetime, depending how the cell format is '
  InvYear = Format(InvDateTime, "YYYY")
  ' compose the query to get the Auto No '
  sql = "SELECT ISNULL(MAX([Auto No]),0) AS MaxNo FROM ExcelData"
  sql += " WHERE [Invoice No] = '" + InvNo + "' "
  sql += " AND YEAR([Invoice Date]) = '" + InvYear + "'"
  Set rsCheck = conn.Execute(sql) ' get the Auto No '
  AutoNo = rsCheck.Fields("MaxNo").Value + 1
  ' compose the query to store the invoices '
  sql = "INSERT INTO ExcelData ("
  sql += "ProductId, "
  sql += "[Invoice No], "
  sql += "[Invoice Date], "
  sql += "Price, "
  sql += "Quantity, "
  sql += "[Auto No]"
  sql += ") VALUES ("
  sql += "'" + Trim(rs.Fields("ProductId").Value) + "',"
  sql += "'" + InvNo + "',"
  sql += "'" + Format(InvDateTime, fmtString) + "',"
  sql += CCur(Trim(rs.Fields("Price").Value)) + ","
  sql += CSng(Trim(rs.Fields("Quantity").Value)) + ","
  sql += AutoNo 
  sql += ")"
  conn.Execute(sql) ' store the invoice '
  rs.MoveNext
Loop

恕我直言,如果您在表格中存储本机数据类型而不是所有文本值会更好,那么您可能还需要检查Excel 单元格的数据类型并提供正确的数据类型转换目标表的类型。 抱歉,我相信数据类型转换的主题太宽泛,不适合这里 - 您最好发布一些新问题。

如果您希望将所有值存储为文本以避免所有这些无聊的数据类型转换,我建议您以YYYY-MM-DD HH:MM:SS(24,no AM / PM)格式存储日期并且AutoNo采用固定长度格式001..002..003,因此它们至少可以正确排序。

<强> EDIT3:

如果基于上述代码段的导入已经过测试并且有效,您可以使用Excel文件的确切日期时间重写对已导入行的检查,如下所示:

fmtString = "YYYY-MM-DD hh:mm:ss" ' you should adapt this to your need '
rs.Open "SELECT * FROM [" & strSheet & "$]", con, adOpenForwardOnly
Do Until rs.EOF
  InvNo = Trim(rs.Fields("InvoiceNo").Value)
  InvDateTime = CDate(rs.Fields("Invoice Date").Value)
  ProdId = Trim(rs.Fields("ProductId").Value)
  ' compose the query to get the same invoice line '
  sql = "SELECT COUNT(*) AS ThisLine FROM ExcelData"
  sql += " WHERE [Invoice No] = '" + InvNo + "' "
  sql += " AND [Invoice Date] = '" + Format(InvDateTime, fmtString) + "'"
  sql += " AND [ProductId] = '" + ProdId + "' "
  Set rsCheck = conn.Execute(sql) ' get the current line '
  If rsCheck.Fields("ThisLine").Value = 0 Then
    ' compose the query to get the Auto No '
    ...
    ...
    conn.Execute(sql) ' store the invoice '
  End If
  rs.MoveNext
Loop

如果您的数据有足够的时间分辨率,我相信您可以跳过相同数量的支票,直至您,但无论如何,您应该调查Excel文件中的发票日期字段的内容。