[{"data":1,"prerenderedAt":634},["ShallowReactive",2],{"blog:2008:dlookup-for-excel":3,"blogMore-Development":620,"comments-dlookup-for-excel":633},{"id":4,"title":5,"body":6,"category":602,"commentCount":91,"date":603,"description":604,"excerpt":605,"extension":606,"filenames":607,"hidden":608,"image":607,"meta":609,"minutes":91,"navigation":87,"path":610,"seo":611,"showCategory":607,"stem":612,"tags":613,"updated":607,"url":617,"wordCount":618,"__hash__":619},"content\u002Fblog\u002F2008\u002Fdlookup-for-excel.md","DLookup for Excel",{"type":7,"value":8,"toc":598},"minimark",[9,18,21,360,367,372,375,420,431,486,496,558,561,565,568,585,588,594],[10,11,12,13,17],"p",{},"I had to do a couple of ad-hoc Excel jobs today and found that while Excel has a ",[14,15,16],"code",{},"VLookup"," function for spreadsheet\u002Franges it doesn’t have one for databases.",[10,19,20],{},"It’s been a while since I touched VBA and Access but the DLookup function was useful so here it is for Excel. Read the warnings below before you use it!",[22,23,28],"pre",{"className":24,"code":25,"language":26,"meta":27,"style":27},"language-vb shiki shiki-themes everforest-light dracula","Public Function DLookup(expression As String, domain As String, criteria As String, Optional connectionString As String)\n\n    Dim con As ADODB.connection\n    Set con = New ADODB.connection\n    If IsMissing(connectionString) Then\n        con.Open \"Driver={SQL Server};Server=abc;Database=def;Trusted_Connection=Yes;\"\n    Else\n        con.Open connectionString\n    End If\n\n    Dim rs As ADODB.Recordset\n    Dim sql As String\n    sql = \"SELECT TOP 1 \" + expression + \" FROM \" + domain + \" WHERE \" + criteria\n    Set rs = con.Execute(sql)\n    If Not rs.EOF Then DLookup = rs(0)\n    rs.Close\n    Set rs = Nothing\n\n    con.Close\n    Set con = Nothing\n\nEnd Function\n","vb","",[14,29,30,82,89,106,124,140,157,163,169,175,180,195,208,259,278,309,315,327,332,338,349,354],{"__ignoreMap":27},[31,32,35,39,43,47,51,54,58,61,63,65,68,70,72,75,77,79],"span",{"class":33,"line":34},"line",1,[31,36,38],{"class":37},"s9HRq","Public",[31,40,42],{"class":41},"sXAHl"," Function ",[31,44,46],{"class":45},"sS4Kt","DLookup",[31,48,50],{"class":49},"s6Vpi","(expression ",[31,52,53],{"class":37},"As",[31,55,57],{"class":56},"snuxY"," String",[31,59,60],{"class":49},", domain ",[31,62,53],{"class":37},[31,64,57],{"class":56},[31,66,67],{"class":49},", criteria ",[31,69,53],{"class":37},[31,71,57],{"class":56},[31,73,74],{"class":49},", Optional connectionString ",[31,76,53],{"class":37},[31,78,57],{"class":56},[31,80,81],{"class":49},")\n",[31,83,85],{"class":33,"line":84},2,[31,86,88],{"emptyLinePlaceholder":87},true,"\n",[31,90,92,95,98,100,103],{"class":33,"line":91},3,[31,93,94],{"class":41},"    Dim",[31,96,97],{"class":49}," con ",[31,99,53],{"class":37},[31,101,102],{"class":56}," ADODB",[31,104,105],{"class":49},".connection\n",[31,107,109,112,115,118,121],{"class":33,"line":108},4,[31,110,111],{"class":41},"    Set ",[31,113,114],{"class":49},"con ",[31,116,117],{"class":37},"=",[31,119,120],{"class":41}," New ",[31,122,123],{"class":49},"ADODB.connection\n",[31,125,127,131,134,137],{"class":33,"line":126},5,[31,128,130],{"class":129},"smiwp","    If",[31,132,133],{"class":45}," IsMissing",[31,135,136],{"class":49},"(connectionString) ",[31,138,139],{"class":129},"Then\n",[31,141,143,146,150,154],{"class":33,"line":142},6,[31,144,145],{"class":49},"        con.Open ",[31,147,149],{"class":148},"spsLl","\"",[31,151,153],{"class":152},"sJFhe","Driver={SQL Server};Server=abc;Database=def;Trusted_Connection=Yes;",[31,155,156],{"class":148},"\"\n",[31,158,160],{"class":33,"line":159},7,[31,161,162],{"class":129},"    Else\n",[31,164,166],{"class":33,"line":165},8,[31,167,168],{"class":49},"        con.Open connectionString\n",[31,170,172],{"class":33,"line":171},9,[31,173,174],{"class":129},"    End If\n",[31,176,178],{"class":33,"line":177},10,[31,179,88],{"emptyLinePlaceholder":87},[31,181,183,185,188,190,192],{"class":33,"line":182},11,[31,184,94],{"class":41},[31,186,187],{"class":49}," rs ",[31,189,53],{"class":37},[31,191,102],{"class":56},[31,193,194],{"class":49},".Recordset\n",[31,196,198,200,203,205],{"class":33,"line":197},12,[31,199,94],{"class":41},[31,201,202],{"class":49}," sql ",[31,204,53],{"class":37},[31,206,207],{"class":56}," String\n",[31,209,211,214,216,219,222,224,227,230,233,235,238,240,242,245,247,249,252,254,256],{"class":33,"line":210},13,[31,212,213],{"class":49},"    sql ",[31,215,117],{"class":37},[31,217,218],{"class":148}," \"",[31,220,221],{"class":152},"SELECT TOP 1 ",[31,223,149],{"class":148},[31,225,226],{"class":37}," +",[31,228,229],{"class":49}," expression ",[31,231,232],{"class":37},"+",[31,234,218],{"class":148},[31,236,237],{"class":152}," FROM ",[31,239,149],{"class":148},[31,241,226],{"class":37},[31,243,244],{"class":49}," domain ",[31,246,232],{"class":37},[31,248,218],{"class":148},[31,250,251],{"class":152}," WHERE ",[31,253,149],{"class":148},[31,255,226],{"class":37},[31,257,258],{"class":49}," criteria\n",[31,260,262,264,267,269,272,275],{"class":33,"line":261},14,[31,263,111],{"class":41},[31,265,266],{"class":49},"rs ",[31,268,117],{"class":37},[31,270,271],{"class":49}," con.",[31,273,274],{"class":45},"Execute",[31,276,277],{"class":49},"(sql)\n",[31,279,281,283,286,289,292,295,297,300,303,307],{"class":33,"line":280},15,[31,282,130],{"class":129},[31,284,285],{"class":37}," Not",[31,287,288],{"class":49}," rs.EOF ",[31,290,291],{"class":129},"Then",[31,293,294],{"class":49}," DLookup ",[31,296,117],{"class":37},[31,298,299],{"class":45}," rs",[31,301,302],{"class":49},"(",[31,304,306],{"class":305},"s3Ipq","0",[31,308,81],{"class":49},[31,310,312],{"class":33,"line":311},16,[31,313,314],{"class":49},"    rs.Close\n",[31,316,318,320,322,324],{"class":33,"line":317},17,[31,319,111],{"class":41},[31,321,266],{"class":49},[31,323,117],{"class":37},[31,325,326],{"class":305}," Nothing\n",[31,328,330],{"class":33,"line":329},18,[31,331,88],{"emptyLinePlaceholder":87},[31,333,335],{"class":33,"line":334},19,[31,336,337],{"class":49},"    con.Close\n",[31,339,341,343,345,347],{"class":33,"line":340},20,[31,342,111],{"class":41},[31,344,114],{"class":49},[31,346,117],{"class":37},[31,348,326],{"class":305},[31,350,352],{"class":33,"line":351},21,[31,353,88],{"emptyLinePlaceholder":87},[31,355,357],{"class":33,"line":356},22,[31,358,359],{"class":41},"End Function\n",[10,361,362,363,366],{},"Copy and paste the code above into an Excel module and replace the ",[14,364,365],{},"Driver=..."," with what you want to be your default connection.",[368,369,371],"h3",{"id":370},"some-examples-of-use","Some examples of use:",[10,373,374],{},"To select the Name column from the Customers table where the numeric ID is held in column 2.",[22,376,378],{"className":24,"code":377,"language":26,"meta":27,"style":27},"=DLookup(\"Name\",\"Customers\",\"ID=\" & A2)\n",[14,379,380],{"__ignoreMap":27},[31,381,382,384,386,388,390,393,395,398,400,403,405,407,409,412,414,417],{"class":33,"line":34},[31,383,117],{"class":37},[31,385,46],{"class":45},[31,387,302],{"class":49},[31,389,149],{"class":148},[31,391,392],{"class":152},"Name",[31,394,149],{"class":148},[31,396,397],{"class":49},",",[31,399,149],{"class":148},[31,401,402],{"class":152},"Customers",[31,404,149],{"class":148},[31,406,397],{"class":49},[31,408,149],{"class":148},[31,410,411],{"class":152},"ID=",[31,413,149],{"class":148},[31,415,416],{"class":37}," &",[31,418,419],{"class":49}," A2)\n",[10,421,422,423,426,427,430],{},"To return ",[14,424,425],{},"Forename"," and ",[14,428,429],{},"Surname"," columns joined together with a space from the Contacts table in the crm database using the postcode from column 5:",[22,432,434],{"className":24,"code":433,"language":26,"meta":27,"style":27},"=DLookup(\"Forname + ' ' + Surname\",\"crm..Contact\",\"PostCode='\" & A5 & \"'\")\n",[14,435,436],{"__ignoreMap":27},[31,437,438,440,442,444,446,449,451,453,455,458,460,462,464,467,469,471,474,477,479,482,484],{"class":33,"line":34},[31,439,117],{"class":37},[31,441,46],{"class":45},[31,443,302],{"class":49},[31,445,149],{"class":148},[31,447,448],{"class":152},"Forname + ' ' + Surname",[31,450,149],{"class":148},[31,452,397],{"class":49},[31,454,149],{"class":148},[31,456,457],{"class":152},"crm..Contact",[31,459,149],{"class":148},[31,461,397],{"class":49},[31,463,149],{"class":148},[31,465,466],{"class":152},"PostCode='",[31,468,149],{"class":148},[31,470,416],{"class":37},[31,472,473],{"class":49}," A5 ",[31,475,476],{"class":37},"&",[31,478,218],{"class":148},[31,480,481],{"class":152},"'",[31,483,149],{"class":148},[31,485,81],{"class":49},[10,487,422,488,491,492,495],{},[14,489,490],{},"Description"," from a ",[14,493,494],{},"Products"," table held in another connection using a partial like match from column 1:",[22,497,499],{"className":24,"code":498,"language":26,"meta":27,"style":27},"=DLookup(\"Description\",\"Products\",\"OrderCode LIKE '\" & A1 & \"%'\", \"DSN=SecondaryDSN\")\n",[14,500,501],{"__ignoreMap":27},[31,502,503,505,507,509,511,513,515,517,519,521,523,525,527,530,532,534,537,539,541,544,546,549,551,554,556],{"class":33,"line":34},[31,504,117],{"class":37},[31,506,46],{"class":45},[31,508,302],{"class":49},[31,510,149],{"class":148},[31,512,490],{"class":152},[31,514,149],{"class":148},[31,516,397],{"class":49},[31,518,149],{"class":148},[31,520,494],{"class":152},[31,522,149],{"class":148},[31,524,397],{"class":49},[31,526,149],{"class":148},[31,528,529],{"class":152},"OrderCode LIKE '",[31,531,149],{"class":148},[31,533,416],{"class":37},[31,535,536],{"class":49}," A1 ",[31,538,476],{"class":37},[31,540,218],{"class":148},[31,542,543],{"class":152},"%'",[31,545,149],{"class":148},[31,547,548],{"class":49},", ",[31,550,149],{"class":148},[31,552,553],{"class":152},"DSN=SecondaryDSN",[31,555,149],{"class":148},[31,557,81],{"class":49},[10,559,560],{},"I think you get the idea!",[368,562,564],{"id":563},"caveats","Caveats",[10,566,567],{},"There are a few caveats you need to be aware of using this function:",[569,570,571,575,580],"ul",{},[572,573,574],"li",{},"It only returns the first value of the first row",[572,576,577,579],{},[14,578,46],{}," is not efficient as it opens connection each time it is referenced. This could put a lot of strain on your server.",[572,581,582],{},[14,583,584],{},"DLookup syntax is open-ended and has some attack vectors",[10,586,587],{},"If that doesn’t scare you then give it a shot. As usual no warranty expressed or implied!",[10,589,590],{},[591,592,593],"em",{},"[)amien",[595,596,597],"style",{},"html pre.shiki code .s9HRq, html code.shiki .s9HRq{--shiki-default:#F57D26;--shiki-dark:#FF79C6}html pre.shiki code .sXAHl, html code.shiki .sXAHl{--shiki-default:#3A94C5;--shiki-dark:#FF79C6}html pre.shiki code .sS4Kt, html code.shiki .sS4Kt{--shiki-default:#8DA101;--shiki-dark:#50FA7B}html pre.shiki code .s6Vpi, html code.shiki .s6Vpi{--shiki-default:#5C6A72;--shiki-dark:#F8F8F2}html pre.shiki code .snuxY, html code.shiki .snuxY{--shiki-default:#3A94C5;--shiki-default-font-style:inherit;--shiki-dark:#8BE9FD;--shiki-dark-font-style:italic}html pre.shiki code .smiwp, html code.shiki .smiwp{--shiki-default:#F85552;--shiki-dark:#FF79C6}html pre.shiki code .spsLl, html code.shiki .spsLl{--shiki-default:#DFA000;--shiki-dark:#E9F284}html pre.shiki code .sJFhe, html code.shiki .sJFhe{--shiki-default:#DFA000;--shiki-dark:#F1FA8C}html pre.shiki code .s3Ipq, html code.shiki .s3Ipq{--shiki-default:#DF69BA;--shiki-dark:#BD93F9}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":27,"searchDepth":84,"depth":84,"links":599},[600,601],{"id":370,"depth":91,"text":371},{"id":563,"depth":91,"text":564},"Development","2008-02-28T13:33:02+00:00","I had to do a couple of ad-hoc Excel jobs today and found that while Excel has a VLookup function for spreadsheet\u002Franges it doesn’t have one for databases.","[object Object]","md",null,false,{},"\u002Fblog\u002F2008\u002Fdlookup-for-excel",{"title":5,"description":604},"blog\u002F2008\u002Fdlookup-for-excel",[614,615,616],"Microsoft","Excel","SQL Server","\u002Fblog\u002F2008\u002Fdlookup-for-excel\u002F",488,"sNlaHAxJLL3ics33e2esdAqJ5S_K-jXLAHlYzz-AsbY",[621,625,629],{"title":622,"date":623,"url":624},"Transactions in the MongoDB EF Core Provider","2025-10-25","\u002Fblog\u002F2025\u002Fmongodb-explicit-transactions\u002F",{"title":626,"date":627,"url":628},"Queryable Encryption with the MongoDB EF Core Provider","2025-09-22","\u002Fblog\u002F2025\u002Fmongodb-queryable-encryption\u002F",{"title":630,"date":631,"url":632},"Lazy Loading with EF Core Proxies","2025-04-02","\u002Fblog\u002F2025\u002Fef-proxies\u002F",[],1780900528535]