2010-10-24 27 views
17

Chcę połączyć się z bazą danych MongoDB używając makr Excela, czy ktoś wie jak acomplish to zadanie?Jak podłączyć MongoDB z Excela

+2

Od prawie tak dawna, jak to pytanie było zadawane, w trackerze istniał bilet do MongoDB z żądaniem to samo: https://jira.mongodb.org/browse/SERVER-2 063 –

Odpowiedz

3

Prosty sposób jest

  1. utworzyć C# dll do interakcji z Mongo db poprzez dostępne C# kierowców.
  2. Make it Com widoczne (w Assemblyinfo.cs), budować go i zarejestrować go
  3. Przejdź do excel makro -> Edytor Visual Basic
  4. Kliknij Narzędzia-> odniesienia i wybierz swoją siedzibę zespół
  5. I użyj go w swoim VBA, w ten sposób.

.

Private Sub CallMongo() 
    Dim mongoObj As New MyMongoAssembly 
    mongoObj.AddItem("adas"); 
End Sub 

to wszystko ..

+2

żartujesz? –

+0

Czy jest coś zabawnego? – RameshVel

+9

Z poważaniem rozważę usunięcie słowa "prosty" z pierwszego zdania odpowiedzi. Jest to z pewnością realistyczne rozwiązanie dla kogoś z wymaganymi umiejętnościami i czasem, ale z pewnością nie jest to proste rozwiązanie. –

0

Myślę, że najlepszą odpowiedzią byłoby napisać lub znaleźć sterownika ODBC dla MongoDB. Daj mi znać, jeśli znajdziesz.

Zakazując tego, można napisać frontend internetowy dla mongodb, który renderuje odpowiednie zapytanie do tabeli HTML, i użyć funkcji Excela do analizy tabel HTML ze stron internetowych. Nie tak czysty jak ODBC, ale lepszy niż eksportowanie CSV w kółko.

0

zawsze można spojrzeć na to rozwiązanie, nie próbował go samodzielnie, a to wymaga kilku skokach: http://sqlmag.com/blog/integrating-mongodb-and-open-source-data-stores-power-pivot

+0

Należy pamiętać, że [odpowiedź tylko od łącza] (http://meta.stackoverflow.com/tags/link-only -answers/info) są odradzane, odpowiedzi na pytania powinny być punktem końcowym poszukiwania rozwiązania (a jest to kolejne międzylądowanie odniesień, które z czasem stają się nieaktualne). Proszę rozważyć dodanie samodzielnego streszczenia tutaj, zachowując odnośnik jako odniesienie. – kleopatra

3

Moje własne rozwiązanie było pozwolić Python skleić je razem za pomocą pymongo i win32com. Wtedy jest całkiem proste prowadzenie wszystkiego, co chcesz. W moim przypadku mam pętlę Python po prostu ciągle „słuchać” niektórych komórkach Excel, zadzwoń, czego potrzebuje od Mongo, a następnie umieścić go z powrotem do programu Excel. Jest elastyczny i wiele rzeczy można zrobić w ten sposób. Oto pełna podstawa kodu, ale będziesz musiał zmienić połączenia z Mongodb, aby pasowały do ​​twojej własnej bazy danych. Tutaj również zobaczysz pewne sposoby zmiany kolorów i elementów komórek Excel z poziomu Pythona. Oh Należy wspomnieć, że jest to z pieprzem ANSI sekwencje więc może chcesz uruchomić Pythona z ansicon lub ConEmu.

import win32com.client as win32 
import time # will need this for time parsing 
from optparse import OptionParser 
import pdb  # debugger, when necessary 
import string # for string parsing and the alphabet 
from pymongo import MongoClient 
import inspect 
from datetime import datetime, timedelta, tzinfo 
from dateutil import tz 
from bson.son import SON 
import msvcrt # for getch 
import os 
import sys # for stdout.write 
from collections import OrderedDict 


def parseCmdLine(): 
    parser = OptionParser(description="Retrieve realtime data.") 
    parser.add_option("--f", 
         dest="file", 
         help="filename", 
         default="bbcapture.xls") 
    parser.add_option("--mongohost", 
         dest="mongohost", 
         default="192.168.1.30") 
    parser.add_option("--mongoport", 
         dest="mongoport", 
         type="int", 
         default=27017) 

    (options, args) = parser.parse_args() 
    return(options) 

options = parseCmdLine() # parse the commandline 
client = MongoClient(options.mongohost, options.mongoport) # link to mongo 
db = client.bb # the database 
bbsecs = db.bbsecs # now all the collections 
bbdaily = db.bbdaily 
bbticks = db.bbticks 
linkstatusperiod = False # for the moving period in the top left excel cell showing we're linked 

def ansi(colour = "white", bright = False, back = "black"): 
# ansi colour sequences 
    brit = {True:  "\033[1m", 
      False:  "\033[0m"} 
    colo = {"black": "\033[30m", 
      "red":  "\033[31m", 
      "green": "\033[32m", 
      "yellow": "\033[33m", 
      "blue":  "\033[34m", 
      "magenta": "\033[35m", 
      "cyan":  "\033[36m", 
      "white": "\033[37m"} 
    bakk = {"black": "\033[40m", 
      "red":  "\033[41m", 
      "green": "\033[42m", 
      "yellow": "\033[43m", 
      "blue":  "\033[44m", 
      "magenta": "\033[45m", 
      "cyan":  "\033[46m", 
      "white": "\033[47m"} 
    sys.stdout.write(brit[bright]) 
    sys.stdout.write(colo[colour]) 
    sys.stdout.write(bakk[back]) 


def mdaily(ticker = "USDEUR Curncy", field = "LAST_PRICE", sortdirection = 1, numget = 1000000): 
    ansi("cyan", False) 
    print "\nGetting", ticker, "field", field, "from Mongo...", 
    lister = OrderedDict() 
    #for post in bbdaily.find({"ticker": ticker, "fieldname": field}).limit(numget).sort("time", sortdirection): 
    for post in bbdaily.find({"$query": {"ticker": ticker, "fieldname": field}, "$orderby": {"time": -1}}).limit(numget): 
     lister[str(post["time"])] = post["fieldvalue"] 
    ansi("cyan", True) 
    print "got", len(lister), "values", 
    ansi() 
    return lister 

def mtick(tickers, sortdirection = 1, numget = 1000000): 
    if len(tickers) == 0: 
     return [] 
    else: 
     ansi("green", False) 
     print "\n Getting minutes for for", tickers, 
     tickerdic = OrderedDict() 
     for eachticker in tickers: 
      eachdic = dict() 
      print numget 
      for post in bbticks.find({"ticker": eachticker}).limit(numget): 
       eachdic[post["time"]] = [post["open"], post["high"], post["low"], post["close"]] 
      ansi("green") 
      tickerdic[eachticker] = eachdic 
      print "got", len(eachdic), "for ticker", eachticker, 
     ansi("green", True) 
     print "got", len(tickerdic), "tickers", 
     dates = [set(tickerdic[x].keys()) for x in tickerdic] # get all the dates 
     dates = set.intersection(*dates) # get the unique ones 
     dates = [x for x in dates] # convert to list 
     if sortdirection == -1: 
      dates = sorted(dates, reverse = True) 
     else: 
      dates = sorted(dates, reverse = False) 
     retlist = [[[x, tickerdic[y][x][0], tickerdic[y][x][1], tickerdic[y][x][2], tickerdic[y][x][3]] for x in dates] for y in tickerdic.keys()] 
     ansi() 
     return retlist 

def getsecs(): 
    seclist = [] 
    for post in bbsecs.find(): 
     seclist.append(post["ticker"]) 
    return(seclist) 




def offsetString(startrow, startcol, endrow, endcol): 
    startrowstr = str(startrow) 
    endrowstr = str(endrow) 
    if(startcol > 26): 
     startcolstr = string.uppercase[startcol/26 - 1] + string.uppercase[startcol % 26 - 1] 
    else: 
     startcolstr = string.uppercase[startcol - 1] 
    if(endcol > 26): 
     endcolstr = string.uppercase[endcol/26 - 1] + string.uppercase[endcol % 26 - 1] 
    else: 
     endcolstr = string.uppercase[endcol - 1] 
    return(startcolstr + startrowstr + ":" + endcolstr + endrowstr) 

def main(): 
    excel = win32.gencache.EnsureDispatch("Excel.Application") 
    excel.Visible = 1 
    try: # try to link to the file 
     ansi("red", False) 
     print "Linking to", options.file 
     wb = excel.Workbooks(options.file) 
     ws = wb.Worksheets("MongoData") 
     ansi() 
    except: # not open then try to load it 
     try: 
      ansi("red", False) 
      print "Not open.... trying to open in current directory", os.getcwd() 
      ansi() 
      wb = excel.Workbooks.Open(os.getcwd() + "\\" + options.file) 
      ws = wb.Worksheets("MongoData") 
      ansi() 
     except: # can't load then ask to create it 
      ansi("red", True) 
      print options.file, "not found here. Create? (y/n) ", 
      ansi("yellow", True) 
      response = msvcrt.getch() 
      print response 
      ansi() 
      if response.upper() == "Y": 
       wb = excel.Workbooks.Add() 
       ws = excel.Worksheets.Add() 
       ws.Name = "MongoData" 
       wb.SaveAs(os.getcwd() + "\\" + options.file) 
      else: # don't wanna create it then exit 
       print "bye." 
       return 
    # see if ticks sheet works otherwise add it 
    try: 
     wst = wb.Worksheets("MongoTicks") 
    except: 
     wst = excel.Worksheets.Add() 
     wst.Name = "MongoTicks" 
     wst.Cells(3, 2).Value = 1 
    # see if securities list sheet works otherwise add it 
    try: 
     wall = wb.Worksheets("AllSecurities") 
     wall.Cells(1, 1).Value = "List of all securities" 
     wall.Range("A1:A1").Interior.ColorIndex = 8 
     wall.Range("A:A").ColumnWidth = 22 
    except: 
     wall = excel.Worksheets.Add() 
     wall.Name = "AllSecurities" 
     wall.Cells(1, 1).Value = "List of all securities" 
     wall.Range("A1:A1").Interior.ColorIndex = 8 
     wall.Range("A:A").ColumnWidth = 22 

    ansi("green", True) 
    print "talking to", options.file, 
    ansi("green", False) 
    print "... press any key when this console has the focus, to end communication" 
    ansi() 
    def linkstatusupdate(): 
     global linkstatusperiod 
     if linkstatusperiod: 
      ws.Cells(1, 1).Value = "Talking to Python|" 
      wst.Cells(1, 1).Value = "Talking to Python!" 
      linkstatusperiod = False 
     else: 
      ws.Cells(1, 1).Value = "Talking to Python|" 
      wst.Cells(1, 1).Value = "Talking to Python!" 
      linkstatusperiod = True 
     ws.Cells(1, 2).Value = datetime.now() 
    # daily worksheet header formatting 
    ws.Cells(1, 1).Value = "Excel linked to Python" 
    ws.Cells(1, 3).Value = "Sort direction:" 
    ws.Cells(1, 4).Value = 1 
    ws.Cells(1, 5).Value = "Fetch max:" 
    ws.Cells(2, 1).Value = "Enter tickers:" 
    ws.Cells(3, 1).Value = "Start data:" 
    ws.Cells(4, 1).Value = "End data:" 
    ws.Range("A:A").ColumnWidth = 22 
    ws.Range("B:B").ColumnWidth = 20 
    ws.Range("A2:GS2").Interior.ColorIndex = 19 # beige 200 columns 
    ws.Range("A3:GS4").Interior.ColorIndex = 15 # grey 
    ws.Range("A2").Interior.ColorIndex = 3 # red 
    ws.Range("A3:A4").Interior.ColorIndex = 16 # dark grey 
    # minute worksheet header formatting 
    wst.Cells(1, 1).Value = "Excel linked to Python" 
    wst.Cells(2, 1).Value = "Enter tickers:" 
    #wst.Cells(3, 1).Value = "Enter periodicity:" 
    wst.Cells(1, 3).Value = "Sort direction:" 
    wst.Cells(1, 4).Value = 1 
    wst.Cells(1, 5).Value = "Fetch max:" 
    wst.Range("A:A").ColumnWidth = 22 
    wst.Range("B:B").ColumnWidth = 20 
    wst.Range("A2:GS3").Interior.ColorIndex = 19 # beige 200 columns 
    wst.Range("A4:GS5").Interior.ColorIndex = 15 # grey 
    wst.Range("A2:A3").Interior.ColorIndex = 4 # red 
    wst.Range("6:100000").Clear() 
    linkstatusperiod = False 
    oldsecd = [] 
    oldseci = [] 
    oldnumget = oldsortdir = toldnumget = toldsortdir = 0 
    while not msvcrt.kbhit(): 
     try: 
      print "...", wb.Name, 
      securities = ws.Range("B2:GS2").Value[0] 
      sortdir = ws.Cells(1, 4).Value 
      if sortdir == None: 
       sortdir = 1 
      sortdir = int(sortdir) 
      numget = ws.Cells(1, 6).Value 
      if numget == None: 
       numget = 1000000 
      numget = int(numget) 
      securities = [x for x in securities if x is not None] 
      if not ((oldsecd == securities) and (oldnumget == numget) and (oldsortdir == sortdir)): # clear content of cells 
       ws.Range("5:1000000").Clear() 
       ws.Range("B3:GS4").Clear() 
       ws.Range("B3:GS4").Interior.ColorIndex = 15 # grey 
       oldsecd = securities 
       oldnumget = numget 
       oldsortdir = sortdir 
      currentcol = 0 
      for sec in securities: 
       linkstatusupdate() 
       secdata = mdaily(sec, "LAST_PRICE", sortdir, numget) 
       currentrow = 0 
       vallist = [] 
       datelist = [] 
       if sortdir == -1: 
        sortedkeys = sorted(secdata, reverse = True) 
       else: 
        sortedkeys = sorted(secdata, reverse = False) 
       for eachkey in sortedkeys: 
        datelist.append(eachkey) 
        vallist.append(secdata[eachkey]) 
       #now stick them in Excel 
       ws.Range(offsetString(5 + currentrow, 2 + currentcol, 5 + currentrow + len(vallist) - 1, 2 + currentcol)).Value = \ 
         tuple([(x,) for x in vallist]) 
       if currentcol == 0: 
        ws.Range(offsetString(5 + currentrow, 1, 5 + currentrow + len(vallist) - 1, 1)).Value = \ 
         tuple([(x,) for x in datelist]) 
       if len(sortedkeys) > 0: 
        ws.Cells(3, 2 + currentcol).Value = sortedkeys[len(sortedkeys) - 1].split()[0] # start data date 
        ws.Cells(4, 2 + currentcol).Value = sortedkeys[0].split()[0] # end data date 
       currentcol += 1 
      # now do the tick data 
      securitiest = wst.Range("B2:GS2").Value[0] 
      securitiest = [x for x in securitiest if x is not None] 
      tsortdir = wst.Cells(1, 4).Value 
      if tsortdir == None: 
       tsortdir = 1 
      tsortdir = int(tsortdir) 
      tnumget = wst.Cells(1, 6).Value 
      if tnumget == None: 
       tnumget = 1000000 
      tnumget = int(tnumget) 
      if not ((oldseci == securitiest) and (toldnumget == tnumget) and (toldsortdir == tsortdir)): # clear the contents of the cells 
       wst.Range("6:1000000").Clear() 
       wst.Range("B4:GS5").Clear() 
       wst.Range("B4:GS5").Interior.ColorIndex = 15 # grey 
       oldseci = securitiest 
       toldnumget = tnumget 
       toldsortdir = tsortdir 
      secdata = mtick(securitiest, tsortdir, tnumget) 
      currentsec = 0 
      for x in secdata: 
       sender = [tuple(y[1:5]) for y in x] 
       wst.Range(offsetString(6, 2 + currentsec * 4, 6 + len(x) - 1, 5 + currentsec * 4)).Value = sender 
       if currentsec == 0: # then put the dates in 
        dates = [tuple([y[0], ]) for y in x] 
        wst.Range(offsetString(6, 1, 6 + len(x) - 1, 1)).Value = dates 
       wst.Range(offsetString(5, 2 + currentsec * 4, 5, 5 + currentsec * 4)).Value = ["open", "high", "low", "close"] 
       currentsec += 1 
      for x in range(0, len(securitiest)): 
       wst.Cells(4, 2 + x * 4).Value = securitiest[x] 
      linkstatusupdate() 
      allsecs = tuple([(yy,) for yy in getsecs()]) 
      wall.Range(offsetString(2, 1, len(allsecs) + 1, 1)).Value = allsecs 

     except: 
      print "\nExcel busy", 
     time.sleep(1) 

    endchar = msvcrt.getch() # capture the last character so it doesn't go to console 
    print "\nbye." 


if __name__ == "__main__": 
    main() 
7

Shell Podejście

Prawie wszystko, co łączy się z wiersza poleceń można uzyskać z Shell.

Oto przykład goły, które łączy się z działającej instancji MongoDB i drukuje zapytanie do okna Immediate. Musisz dodać odniesienie do 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 

Tylko drukowanie surowe ciągi JSON nie jest bardzo ekscytujące i użyteczne, jednak.Możesz napisać własny analizator składni JSON, ale w tym przykładzie użyjemy VBA-JSON przez Tima Halla (możesz find it on GitHub).

W chwili pisania tego artykułu występuje jeden problem z VBA-JSON, który należy rozwiązać, analizując ciągi zwracane z MongoDB. Wszelkie wartości zawierające nawiasy, np. "_id": ObjectId("..."), spowoduje błąd. Szybkim i brudnym rozwiązaniem jest użycie polecenia RegEx do wyczyszczenia łańcucha dla analizatora składni. Będziesz musiał odwołać się do biblioteki Microsoft VBScript Regular Expressions 5.5, aby następująca funkcja działała.

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 

Możemy analizować JSON zwrócony z MongoDB i dodać każdy obiekt do Collection. Uzyskanie dostępu do wartości staje się dość proste.

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 

... Który będzie produkować następujące wyjście z MongoDB Example Dataset.

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 

pułapek

  • ReadLine i WriteLineblokujące funkcje.
  • Okno otwarte przez Execnie może być ukryte.

Rozwiązaniem oba powyższe byłoby wykorzystanie podejścia dwuwarstwową, gdzie VBA wywołuje ukrytą skrypt korzystając wsh.Run, który następnie uruchamia Exec (a także inny kod, który współdziała z proc) . Minusem tego podejścia jest to, że StdIn (i do StdOut) musi być zapisany w pliku.

+0

To jest najlepsze rozwiązanie. Nie wymaga żadnych licencji, żadnej dodatkowej warstwy (python/C#), nie ma zarządzania plikami i jest naprawdę bardzo elegancki. Istnieje kilka dziwnych metod ukrywania okna exec, opisanych tutaj - http://stackoverflow.com/questions/32297699/hide-command-prompt-window-when-using-exec, ale ich nie sprawdziłem. – lukehawk

2

Dostępne są sterowniki ODBC z postępu (wymienione poniżej), z easysoft i cdata.
Próbowałem z postępem i dobrze to działa. Wszystkie te sterowniki są licencjonowanym oprogramowaniem i dostępna jest wersja próbna.

Najprostszym w użyciu jest cdata Excel Add-In, który może wyszukiwać, aktualizować , a także umożliwia używanie formuły opartej na Excelu o nazwie & VBA. Jest też licencjonowany.

Jeszcze jednym sposobem jest zapytanie za pomocą pymongo w python zamiast klienta mongo, zrzucanie wyników do pliku csv i importowanie pliku CSV przez VBA. Querying mongoDB z Pythona jest dość łatwe.
Oto przykład zapytania z MongoDB Przykładowy zestaw danych.

Plik Pythona dla zapytania "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() 

Wykonanie tego skryptu wypisze na standardowe wyjście jako

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 

Excel VBA makro używając WshShell, macro_queryMongoDB()

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 

Running to makro będzie zapełnić oddzielonych przecinkami dane w wierszach:

enter image description here

1

Mogę powtórzyć inne odpowiedzi, które odnoszą się do używania sterownika ODBC do łączenia się z danymi MongoDB w programie Excel. Problem polega oczywiście na tym, że nie ma możliwości użycia makr.

Jak wspomniała Irfan, CData Excel Add-In pozwoli ci to zrobić. (Pełne ujawnienie, pracuję dla CData Software). Można przeczytać o podłączeniu do MongoDB użyciu makr w naszym Help documentation, ale podaję odpowiedni fragment kodu, żeby wykazać podstawową funkcjonalność odczytu danych MongoDB w Excel:

Sub DoSelect() 
    On Error GoTo Error 
    p_id = InputBox("_id:", "Get _id") 
    If p_id = False Then 
    Exit Sub 
    End If 
    Dim module As New ExcelComModule 
    module.SetProviderName ("MongoDB") 
    Cursor = Application.Cursor 
    Application.Cursor = xlWait 
    Dim nameArray 
    nameArray = Array("_idparam") 
    Dim valueArray 
    valueArray = Array(p_id) 
    Query = "SELECT City, CompanyName FROM Customers WHERE _id = @_idparam" 
    module.SetConnectionString ("Server=127.0.0.1;Port=27017;Database=test;User=test;Password=test;") 
    If module.Select(Query, nameArray, valueArray) Then 
    Dim ColumnCount As Integer 
    ColumnCount = module.GetColumnCount 
    For Count = 0 To ColumnCount - 1 
     Application.ActiveSheet.Cells(1, Count + 1).Value = module.GetColumnName(Count) 
    Next 
    Dim RowIndex As Integer 
    RowIndex = 2 
    While (Not module.EOF) 
     For columnIndex = 0 To ColumnCount - 1 
     If Conversion.CInt(module.GetColumnType(columnIndex)) = Conversion.CInt(vbDate) And Not IsNull(module.GetValue(columnIndex)) Then 
      Application.ActiveSheet.Cells(RowIndex, columnIndex + 1).Value = Conversion.CDate(module.GetValue(columnIndex)) 
     Else 
      Application.ActiveSheet.Cells(RowIndex, columnIndex + 1).Value = module.GetValue(columnIndex) 
     End If 
     Next 
     module.MoveNext 
     RowIndex = RowIndex + 1 
    Wend 
    MsgBox "The SELECT query successful." 
    Else 
    MsgBox "The SELECT query failed." 
    End If 
    Application.Cursor = Cursor 
    Exit Sub 
Error: 
    MsgBox "ERROR: " & Err.Description 
    Application.Cursor = Cursor 
End Sub 

Nasz 2016 wersja jest aktualnie w wersji beta , więc możesz rozpocząć pracę z danymi MongoDB w Excelu za darmo już dziś.

0

Mówią, że to 3rd party kierowca MongoDB COM wokół: http://na-s.jp/MongoCOM/index.en.html Po zainstalowaniu i przedstawieniu go można uruchomić kwerendy jak

Dim oConn 
    Dim oCursor,o 

    Set oConn = oMng.NewScopedDBConnection(cHostAndPort)     
    Set oCursor = oConn.Query("ec.member", oMng.FJ("{ ""age"": 37 }") 
    Do While oCursor.More 
     Set o = oCursor.Next 
     MsgBox "mname: " & o("mname") 
     MsgBox "dept: " & o("dept") 
     MsgBox "age: " & o("age")  
    Loop 

To jest dla tych, którzy uważa, że ​​De normalizujący struktur MongoDB i tłumaczenie ich na formularz zapytania SQL w locie za każdym razem, gdy potrzebujesz kawałka danych, to przesada ;-)