我正在构建一个宏,该宏将为我的团队自动执行报告。第一部分设置为根据在对话框中选择的唯一标识符查询SQL(使用MS SQL Server Management Studio),然后将这些结果输入步骤2。
构建宏时,我注意到当唯一标识符列表小于9,000时,查询返回的结果与预期的一样。但是,如果我尝试查询超过9000行的任何内容,该宏将无错误运行,但它不会返回结果,而是仅显示最后一个活动窗口。基本上看起来宏没有执行任何操作。
由于宏可以很好地与小型数据集一起使用,并且没有错误,因此我对如何使其在大型数据集上工作感到有些困惑。我们的报告通常超过10,000行。可以作为我的参考吗?任何见识将不胜感激。请让我知道是否需要其他见解。
编辑:
当前代码低于
Sub FilterLov1()
Dim rng As Range
Dim workrng As Range
Dim workrng1 As String
Dim today As String
Dim lastRow As Long
Dim dept As String
Dim class As String
Dim subclass As String
Dim sSQL As String
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim wsname As String
wsname = ActiveSheet.Name
'Set omsid list for SQL query
On Error GoTo Handler
Set workrng = Application.InputBox("Range:", Type:=8)
Application.ScreenUpdating = False
'Set rng = ActiveSheet.Range(workrng)
Dim mystring As String
mystring = RangeToString(workrng)
'Declare the SQL code here
Set cn = New ADODB.Connection
cn.Open "Provider=SQLOLEDB;Data Source=WAPRCN026A;Initial Catalog= STEP_MVIEWS;Integrated Security=SSPI"
sSQL = "select NAME, GuidID, DATASTANDARDS_PATH, PRODUCT_NAME_120, MARKETING_COPY, BULLET01, BULLET02, BULLET03, BULLET04, BULLET05, BULLET06, WORKFLOWSTATE, CHANNELSTATUS, THDONLINESTATUS from STEP_MVIEWS.dbo.[OMSID TO DATASTANDARDS] inner join STEP_MVIEWS.dbo.SCORECARD10_APPROVED on name = OMSID where [omsid] in (" & mystring & ")"
Set rs = New ADODB.Recordset
rs.Open sSQL, cn
'Sheets.Add After:=ActiveSheet
Worksheets.Add.Name = "FiltersLOVRaw"
Worksheets("FiltersLOVRaw").Cells(1, 1).CopyFromRecordset rs
rs.Close
Set rs = Nothing
cn.Close
Set cn = Nothing
Cells.Select
'Add Column Headers here for export file
Sheets("FiltersLOVRaw").Select
Rows("1:1").Select
Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
Cells(1, 1).value = "OMSID"
Cells(1, 2).value = "PARENT LEAF GUID"
Cells(1, 3).value = "FILE PATH"
Cells(1, 4).value = "PRODUCT NAME (120)"
Cells(1, 5).value = "MARKETING COPY (1500)"
Cells(1, 6).value = "BULLET 01"
Cells(1, 7).value = "BULLET 02"
Cells(1, 8).value = "BULLET 03"
Cells(1, 9).value = "BULLET 04"
Cells(1, 10).value = "BULLET 05"
Cells(1, 11).value = "BULLET 06"
Cells(1, 12).value = "WORKFLOW STATUS"
Cells(1, 13).value = "CHANNEL STATUS"
Cells(1, 14).value = "THD ONLINE STATUS"
Cells.Select
With ActiveSheet
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
End With
'Sheets.Add
'ActiveSheet.Name = "Export"
'Rows(x - 1).EntireRow.Delete
'Cells.Select
Range("A1").Select
Handler:
Exit Sub
End Sub
Function RangeToString(ByVal MyRange As Range) As String
RangeToString = ""
If Not MyRange Is Nothing Then
Dim myCell As Range
For Each myCell In MyRange
RangeToString = RangeToString & ",'" & myCell.value & "'"
Next myCell
'Remove extra comma
RangeToString = Right(RangeToString, Len(RangeToString) - 1)
'RangeToString = Left(RangeToString, Len(RangeToString) - 1)
End If
End Function
答案 0 :(得分:0)
我知道在Oracle中,使用import os
import subprocess
os.chdir(r'filepath')
subprocess.check_call([r"filepath\your_.exe_app", 'your_input'])
子句的值限制为1,000。
根据this post,有一个限制(在SQL Server中),成千上万。建议将ID列表加载到表中,然后对表进行查询。
答案 1 :(得分:0)
在IN子句中明确地在括号内包含大量值(用逗号分隔的数千个值),会消耗资源并返回错误8623或8632。
错误8623:
The query processor ran out of internal resources and could not produce a query plan. This is a rare event and only expected for extremely complex queries or queries that reference a very large number of tables or partitions. Please simplify the query. If you believe you have received this message in error, contact Customer Support Services for more information.
错误8632:
Internal error: An expression services limit has been reached. Please look for potentially complex expressions in your query, and try to simplify them.
要变通解决此问题,将项目存储在表的IN列表中,并在IN子句中使用SELECT子查询。
可以在SQL Server Management Studio中运行的示例
(或者,如果您没有(免费的)SSMS版本,则直接从Excel对数据库进行查询。)
如果要保留表格,请注释掉DROP语句。
--Sample SQL https://stackoverflow.com/questions/51252536/sql-vba-query-will-only-return-results-on-small-dataset/
IF NOT EXISTS (SELECT * FROM sys.schemas WHERE name = N'CC')
BEGIN
-- Create a new schema name so it does not interfere with existing tables
EXEC sys.sp_executesql N'CREATE SCHEMA [CC] AUTHORIZATION [dbo]'
-- Create the table that holds the values which your user chooses
CREATE TABLE [CC].[KeyList]([RowKeysYouWant] [int] NOT NULL) ON [PRIMARY]
ALTER AUTHORIZATION ON [CC].[KeyList] TO SCHEMA OWNER
-- This is the existing table which has your data in it
CREATE TABLE [CC].[TableWithData]([pk] [int] NOT NULL,
[data1] [char](2) NULL,[data2] [char](2) NULL) ON [PRIMARY]
ALTER AUTHORIZATION ON [CC].[TableWithData] TO SCHEMA OWNER
-- here are the rows that you want (put list of chosen items in here)
INSERT [CC].[KeyList] ([RowKeysYouWant]) VALUES (1),(2),(3),(5),(7)
-- this is your data table (fields data1 and data2 become null by default)
INSERT [CC].[TableWithData] ([pk]) VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9)
-- This is the select you use to grab all the records in table KeyList
SELECT * FROM CC.TableWithData WHERE pk IN (SELECT RowKeysYouWant FROM CC.KeyList)
DROP TABLE [CC].[TableWithData]; DROP TABLE [CC].[KeyList]; DROP SCHEMA [CC]
END
GO
您将需要权限来创建模式和创建表以运行它。
如果您没有这些权限,只需在家用PC上安装SQL Server Express版本的副本并在其中运行脚本即可。
首先使您的SQL工作,然后担心如何使其在VBA中工作。 :-)