几乎任何与命令行接口的东西都可以通过Shell访问.
这是一个简单的示例,它连接到正在运行的MongoDB实例并将查询打印到立即窗口.你需要添加一个引用Windows Script Host Object Model
.
Private Sub Test()
Dim wsh As New WshShell
Dim proc As WshExec
Dim line As String
Set proc = wsh.Exec("mongo")
With proc
.StdIn.WriteLine "use test"
.StdIn.WriteLine "db.restaurants.find({""address.zipcode"":""10075""})"
.StdIn.WriteLine "quit()"
Do While .Status = WshRunning
line = .StdOut.ReadLine
If line = "Type ""it"" for more" Then
.StdIn.WriteLine "it"
ElseIf line Like "{*" Then
Debug.Print line
End If
DoEvents
Loop
End With
End Sub
Run Code Online (Sandbox Code Playgroud)
然而,仅打印原始JSON字符串并不是非常令人兴奋或有用.您可以编写自己的JSON解析器,但是,对于此示例,我们将使用Tim Hall的VBA-JSON(您可以在GitHub上找到它).
在撰写本文时,在使用它来解析从MongoDB返回的字符串时,必须解决VBA-JSON的一个问题.例如"_id": ObjectId("...")
,包含括号的任何值都将引发错误.对此进行快速而又脏的修复是使用RegEx清除解析器的字符串.您需要引用该Microsoft VBScript Regular Expressions 5.5
库才能使用以下函数.
Private Function CleanString(str As String) As String
Dim temp As String
Dim rx As New RegExp
With rx
.IgnoreCase = True
.Global = True
.Pattern = "[a-z]*\(" ' Left
temp = .Replace(str, "")
.Pattern = "\)" ' Right
temp = .Replace(temp, "")
End With
CleanString = temp
End Function
Run Code Online (Sandbox Code Playgroud)
然后我们可以解析从MongoDB返回的JSON并将每个对象添加到a Collection
.访问值变得非常简单.
Private Sub Mongo()
Dim wsh As New WshShell
Dim proc As WshExec
Dim line As String
Dim response As New Collection
Dim json As Object
Set proc = wsh.Exec("mongo")
With proc
.StdIn.WriteLine "use test"
.StdIn.WriteLine "db.restaurants.find({""address.zipcode"":""10075""})"
.StdIn.WriteLine "quit()"
Do While .Status = WshRunning
line = .StdOut.ReadLine
If line = "Type ""it"" for more" Then
.StdIn.WriteLine "it"
ElseIf line Like "{*" Then
response.Add ParseJson(CleanString(line))
End If
DoEvents
Loop
End With
For Each json In response
Debug.Print json("name"), json("address")("street")
Next
End Sub
Run Code Online (Sandbox Code Playgroud)
...将从MongoDB 示例数据集生成以下输出.
Nectar Coffee Shop Madison Avenue
Viand Cafe Madison Avenue
Don Filippo Restaurant Lexington Avenue
Lusardi'S Restaurant Second Avenue
Due Third Avenue
Lenox Hill Grill/Pizza Lexington Avenue
Quatorze Bistro East 79 Street
Luke'S Bar & Grill Third Avenue
Starbucks Coffee Lexington Avenue
New York Jr. League East 80 Street
Doc Watsons 2 Avenue
Serafina Fabulous Pizza Madison Avenue
Canyon Road Grill 1 Avenue
Sushi Of Gari East 78 Street
Run Code Online (Sandbox Code Playgroud)
ReadLine
和WriteLine
被闭锁功能.Exec
无法隐藏.上述两种方法的解决方法是使用两层方法,其中VBA使用隐藏脚本调用wsh.Run
,然后运行Exec
(以及与proc交互的任何其他代码).这种方法的缺点是必须将StdIn(以及某种程度上的StdOut)写入文件.
简单的方法是
。
Private Sub CallMongo()
Dim mongoObj As New MyMongoAssembly
mongoObj.AddItem("adas");
End Sub
Run Code Online (Sandbox Code Playgroud)
就这样..
有 ODBC 驱动程序可以从 progress(下面提到)、easysoft 和 cdata 中获得。
我已经尝试过取得进展,它做得很好。所有这些驱动程序都是许可软件,也提供试用版。
最容易使用的是cdata Excel Add-In,它可以查询、更新并允许使用基于excel的公式和VBA。也是有执照的。
另一种方法是在 python 中使用pymongo而不是 mongo 客户端进行查询,将结果转储到 csv 文件并通过 VBA 导入 csv。从 python 查询 mongoDB 相当容易。
这是从 MongoDB 示例数据集查询的示例。
查询的 Python 文件“queryMongoDB.py”
SERVER = "192.168.43.22" # Replace wit with Server IP or Hostname running mongod
PORT = "27017"
def queryMongoDB():
try:
from pymongo import MongoClient
client = MongoClient("mongodb://" + SERVER + ":" + PORT)
db = client.test
queryResp = db.restaurants.find({'address.zipcode': "11215", 'cuisine': 'Indian'}, {'name': 1, 'address.building': 1, 'address.street': 1, 'borough': 1, '_id': 0})
if queryResp.count() > 0 :
for row in queryResp:
printStr = ""
if 'name' in row:
printStr = row['name'] + ","
else:
printStr = ","
if 'building' in str(row):
printStr = printStr + row['address']['building'] + ","
else:
printStr = printStr + ","
if 'street' in str(row):
printStr = printStr + row['address']['street'] + ","
else:
printStr = printStr + ","
if 'borough' in row:
printStr = printStr + row['borough']
print(printStr)
else:
return -2
return 0
except ImportError:
return -1
queryMongoDB()
Run Code Online (Sandbox Code Playgroud)
执行此脚本将打印到标准输出为
Kinara Indian Restaurant,473,5 Avenue,Brooklyn
Baluchi'S,310,5 Avenue,Brooklyn
Kanan Indian Restaurant,452,3Rd Ave,Brooklyn
New Aarpan,396,5Th Ave,Brooklyn
Indian Spice,351,7Th Ave,Brooklyn
Run Code Online (Sandbox Code Playgroud)
使用 WshShell、macro_queryMongoDB() 的 Excel VBA 宏
Sub macro_queryMongoDB()
Dim pythonExecutable As String
Dim pythonQueryScript As String
pythonExecuatble = "python.exe" ' Path to python interpreter
pythonQueryScript = "queryMongoDB.py" 'Full path to the above Python script
If Dir(pythonExecuatble) <> "" And Dir(pythonQueryScript) <> "" Then
Dim objShell As Object
Dim objWshScriptExec As Object
Dim objStdOut As Object
Set objShell = CreateObject("WScript.Shell")
Set objWshScriptExec = objShell.Exec(pythonExecuatble & " " & pythonQueryScript) ' Execute the Python script
Set objStdOut = objWshScriptExec.StdOut
Set mybook = Excel.ActiveWorkbook
Set mybookSheet = mybook.ActiveSheet
Dim rline As String
Dim strline As String
Dim lineCount As Long
' Parse the results
lineCount = 1
While Not objStdOut.AtEndOfStream
rline = objStdOut.ReadLine
If rline <> "" Then
strline = rline & vbCrLf
mybookSheet.Range(mybookSheet.Cells(lineCount, "A"), mybookSheet.Cells(lineCount, "D")).Value = Split(strline, ",")
lineCount = lineCount + 1
End If
Wend
MsgBox "Query Successful"
Else
MsgBox "Python executable or Python query DB script doesn't exist."
End If
End Sub
Run Code Online (Sandbox Code Playgroud)
运行此宏会将逗号分隔的数据填充到行中