У меня есть форма Access VBA, которую я использую для запуска (посредством вызова оболочки) модуля Python, который загружает несколько файлов, выбранных из файлового диалога Tkinter, в базу данных SQL Server.
из Access
При запуске из Access я заметил следующее:
Для небольшого количества файловэто работает хорошо, запускает модули Python, которые, в свою очередь, запускают некоторые процедуры T-SQL, а затем возвращают идентификатор для первой загруженной даты и времени (оба целых числа)
за умеренное количествофайлов данные загружаются в таблицы SQL Server корректно, но идентификаторы не возвращаются, и программа VBA «зависает» до закрытия окна Python
Для большого количества файловданные не загружаются в таблицы SQL Server, идентификаторы не возвращаются и программа VBA останавливается до закрытия окна Python
из Python
С некоторыми незначительными изменениями модуля Python (замена списка sys.argv на жестко типизированный список и аргумент, как видно из закомментированных строк кода в модуле Python)может инициировать выполнение из Python, и наблюдается следующее:
- Для любого количества файлов данные загружаются в таблицы SQL Server, возвращаются идентификаторы, и программа успешно завершается соответствующим образом
Исследования и испытания Я прошел через множество похожих вопросов о переполнении стека здесь и здесь .Многие из проблем, поднятых в этих темах, связаны с возвращением строки filedialog askopenfilenames, возвращающей строку вместо кортежа, и многочисленными способами преобразования строки в список или кортеж с использованием splitlist, regex и т. Д. Я не обнаружил, что это таквместо этого обнаружив, что filedialog ведет себя так, как ожидалось, и возвращает последовательность строк в виде кортежа, который я преобразовал в список, чтобы предоставить аргумент правильного типа вызываемому модулю.
Код доступа
Function FileUpload(int1Update As Integer, int2Update As Integer, int3Update
As Integer, int4Update As Integer)
Dim objShell As Object, objExec As Object, objOutput As Object
Dim strPython As String, strFile As String, strShell As String,
Dim strOutput As String
Dim intAuto As Integer, intCnt1 As Integer
Set objShell = CreateObject("WScript.Shell")
intAuto = 0
strPython = "C:\Program Files\Microsoft SQL
Server\MSSQL14.SQLSERVER2017\PYTHON_SERVICES\python.exe "
strFile = "C:\Users\dun__\source\repos\MainApp\MainApp\GetFiles.py "
strShell = strPython & strFile & intAuto & " " & int1Update & " " & _
int2Update & " " & int3Update & " " & int4Update
Debug.Print "objShell.exec(" & strShell & ")"
Set objExec = objShell.exec(strShell) 'execute shell command to python
Set objOutput = objExec.StdOut 'obtain standard output from the shell
'command
strOutput = objExec.StdOut.ReadAll
MsgBox "Results of the shell execution:" & vbCrLf & strOutput
Set objOutput = Nothing
Set objShell = Nothing
Set objExec = Nothing
End Function
Код Python
import tkinter
from tkinter import filedialog
import sys
from MainApp import server_uploads
root = tkinter.Tk()
root.withdraw()
file_dir = r'C:\Users\dun__\Google Drive\Programming Stuff'
dnld_flnm = []
while not dnld_flnm:
dnld_flnm = list(filedialog.askopenfilenames(parent=root,
initialdir=file_dir,title='Please select the files'\
' you wish to upload.'))
if dnld_flnm:
during_day = 0
auto_run = int(sys.argv[1])
rtrn_date, rtrn_time = server_uploads(dnld_flnm, during_day,
auto_run, sys.argv)
#auto_run = 0 #delete when tested
#manparams = ['', 0, 0, 0, 0, 0] #delete when tested
#rtrn_date, rtrn_time = server_uploads(dnld_flnm, during_day,
# auto_run, manparams)
if rtrn_time == '':
print('\nFirst DateNo uploaded in batch: %d' % rtrn_date)
else:
print('\nFirst DateNo uploaded in batch %d.\n\n TimeNo '\
'uploaded %d.\n\n' % (rtrn_date, rtrn_time))
else:
print('Please select some files for uploading.')
Вопрос
Кто-нибудь сможет объяснить, что вызываетнесоответствие между поведением, наблюдаемым при инициировании загрузки из Python (работает для любого количества выбранных файлов), и инициированием с помощью команды оболочки из Access VBA в Python (работает для небольшого числа файлов -> частично работает для умеренного количества файлов -> вообще не работает для большого количества файлов)?Обратите внимание, что наблюдаемое поведение не совпадает с наблюдаемым в вопросах о переполнении стека с гиперссылкой, где различные методы были предложены для получения кортежа строк filepath в качестве вывода из файла диалога tkinter.Код выше уже успешно генерирует кортеж строк filepath.