sql-server - 在更改之前通过 ADO 读取 Excel 文件中的值

标签 sql-server excel vba

几周前我学会了如何通过 ADO 更新 Excel 文件。那个时候在改变它之前已经给出了这个值。
现在我想在同一个单元格中添加读取当前值的过程,并在更改之前将值分配给变量!
当前程序如下所示:

Public Sub ChangeNum()
  Dim con As ADODB.Connection, rec As ADODB.Recordset
  Dim sqlstr As String, datasource As String
  Set con = New ADODB.Connection: Set rec = New ADODB.Recordset
  datasource = "D:\DropBox\TraderShare\TraderNum.xlsx"
  Dim sconnect As String
   sconnect = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
            "Data Source=" & datasource & ";" & _
            "Extended Properties=""Excel 12.0 Xml;HDR=YES"";"
  con.Open sconnect
  sqlstr = "UPDATE [Sheet1$] SET [Number] = """ & gsvDocNum & """ WHERE [ID] = """ & svNumRng & """"
  rec.Open sqlstr, con ', adOpenUnspecified, adLockUnspecified 'adLockOptimistic , adOpenStatic, adLockReadOnly
  con.Close
  Set rec = Nothing: Set con = Nothing 
End Sub
gsvDocNum是在初始启动例程开始时声明的全局字符串变量,因此在将当前值读入变量后,UPDATE 将 gsvDocNum + 1 写入文件。svNumRng是以下命名范围之一,PNum , SNum , TNumINum在主例程开始时声明,并在较早阶段确定要查找哪个(如果是采购、销售订单、贸易订单或发票)。

我对 ADO 和 SQL 字符串不太熟悉,我找不到正确的 SELECT 语法来读取当前单元格值并将其分配给变量,然后再使用 UPDATE 更改它。

感谢您的帮助!

好的,背景如下:我们有一个我自己用 Excel vba 编写的管理程序,用于注册购买、订单和发票等。它非常适合我们的要求,但有一个问题,就是要在用户之间保持订单号同步!我们是 3 个在本地使用该程序的用户,每个用户都在注册订单等,但我们通过共享的 DropBox 文件夹共享序列号文件。我的想法是在不打开 Excel 文件的情况下使用 ADO/SQL 比在 Excel 中打开、更改和保存文件要快。原因当然是为了最大限度地减少更新文件的时间,从而最大限度地减少同步到云 Dropfox 位置和其他用户计算机之前的延迟。这是一个简单的 2 列 Excel 文件,TraderNum.xlsx:

ID Number
PNum 16000
SNum 16000
TNum 16132
INum 16173



几周前,我学会了如何在不使用 ADO/SQL 打开文件的情况下从 Excel 中更改其中一个数字(见上文)。但是我发现不断更新 Excel 链接到一个关闭的文件,以便在更改它之前获得当前数字可用,这并不能按预期工作。因此,在使用上面的 ADO/SQL 过程更改它之前,我还想使用 ADO/SQL 来读取/分配特定的当前数字给 Excel 过程中的变量。
所以在两个命令之间的某个地方,rec.Open sconnect 和 con.Close 应该有一个类似于以下的 SQL 字符串:
sqlread = "SELECT """& DocNumOld & """= [Number] FROM [Sheet1$] 其中 [ID] = """& svNumRng & """"
其中 DocNumOld 变量被分配了来自所选 ID 变量 svNumRng 的当前编号。
然后 DocNumNew 变量被赋值,DocNumOld 变量以 1 递增,后跟
sqlUpdate 序列。它应该类似于以下内容:
Public Sub ChangeNum()
Dim con As ADODB.Connection, rec As ADODB.Recordset
Dim sqlRead as String, sqlUpdate As String, datasource As String, sconnect As String
Set con = New ADODB.Connection: Set rec = New ADODB.Recordset
datasource = "D:\DropBox\TraderShare\TraderNum.xlsx"
sconnect = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
            "Data Source=" & datasource & ";" & _
            "Extended Properties=""Excel 12.0 Xml;HDR=YES"";"
con.Open sconnect
sqlRead = "SELECT """ & DocNumOld & """ = [Number] FROM [Sheet1$] Where [ID] = """ & svNumRng & """"
sqlUpdate = "UPDATE [Sheet1$] SET [Number] = """ & DocNumNew & """ WHERE [ID] = """ & svNumRng & """"
rec.Open ???????, con 
????? sqlRead
DocNumNew = DocNumOld + 1
UNION
????? sqlUpdate
con.Close
Set rec = Nothing: Set con = Nothing

结束子

请问你能解决这个吗?

任何人都可以给我一个解决方案,以解决如何使用 ADO/SQL 来读取/分配一个特定的当前数字给 Excel 过程中的变量,然后再用 ADO/SQL 过程更改它?

最佳答案

我担心我不明白你的问题,因为由此产生的评论对我来说没有意义。

重申您的问题:您需要知道某个单元格的值,并能够将其输入到您的代码中。

您已经可以使用 SQL 连接到工作表,您已经知道 SELECT 语句是什么,并且您可能已经知道如何运行它们。幽默我。

sqlRead = "SELECT * FROM [Sheet1$A12:F48]"
Set rec = con.Execute(sqlRead)

现在你有一个记录集 rec包含整个表。假设您想将整个表格的每个值都放在您的即时窗口中:
Do While Not rec.EOF
  For i = 0 To rec.Fields.Count - 1
    Debug.Print rec.Fields(i).Name, rec.Fields(i).Value
  Next
  rec.MoveNext
Loop

不要忘记关闭它,我建议无论如何使用第二个变量名作为更新语句的记录集的名称。
rec.Close

假设您知道单元格将始终位于您选择的表格的第 3 行第 8 列,您可能会:
  For j = 0 to myRowNum-1 'you have set myRowNum equal to 3 earlier'
    rec.MoveNext
  Next
  myOldCellValue = rec.Fields(myColNum-1).value 'you have set myColNum to 8 earlier'
  rec.Close

现在,假设您不确切知道会找到哪一行 myOldCellValue ,但您知道它将在具有唯一 [ID] 1234 的行的第 4 列中找到,您可能会:
sqlRead = "SELECT * FROM [Sheet1$A12:F48] Where [ID] = """ & myIDNum & """" 'you have set myIDNum to 1234 earlier
Set rec = con.Execute(sqlRead)
myOldCellValue = rec.Fields(myColNum-1).value 'you have set myColNum to 4 earlier'
rec.Close

假设您想更新具有该值的每一行(我没有读到您,但为了完整起见),您可能会:
sqlUpdate="UPDATE [Sheet1$] SET [Number] = """ & DocNumNew & """ WHERE [DocNum] = """ & myOldCellValue & """"

关于sql-server - 在更改之前通过 ADO 读取 Excel 文件中的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40951430/

相关文章:

mysql - 关键字 'CONSTRAINT' 附近的语法不正确

mysql - 单列索引和复合列索引有什么区别?

Excel:如何计算多个条件的和积?

vba - 仅复制可见工作表中的单元格并粘贴到下一个免费列 VBA

sql-server - sqlcmd : Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'

SQL Server 选择多个值,如果没有找到值,则返回 null

excel - 使用 workbook_sheetchange 事件在行范围内使数值为负

c# - Microsoft.Office.Interop.Excel 的阅读范围

excel - 隐藏行的动态范围

ms-access - 似乎无法在 VBA 中使用具有属性的接口(interface),我无法弄清楚为什么