I would like to retrieve information from Azure DevOps, with MS Excel VBA, via the Azure DevOps REST API. (Since all other logic is in the MS Excel workbook i have to stick to VBA)
With MS Excel VBA I can’t get around an authorization issue. I do use an Personal Access token (PAT), which I created in Azure DevOps for that purpose.
The VBA code currently used is :
Sub GetADOIncrements()
On Error GoTo ErrorHandler
Dim http As Object
Dim url As String
Dim token As String
Dim jsonResponse As String
Dim json As Object
Dim ws As Worksheet
Dim i As Integer
' Set worksheet
Set ws = ThisWorkbook.Sheets("Projects")
ws.Cells.Clear
' Azure DevOps organisatie en API URL
Dim organization As String
organization = "OdinNB" ' Vervang door jouw organisatie
project = "Odin/FT" ' Vervang door jouw project
' Azure DevOps REST API URL
url = "https://dev.azure.com/" & organization & "/" & project & "/_apis/work/teamsettings/iterations?api-version=7.1"
' Personal Access Token (PAT)
token = "somethingsecret" ' Vervang door jouw PAT
' Create HTTP request
Set http = CreateObject("MSXML2.ServerXMLHTTP")
http.Open "GET", url, False
http.setRequestHeader "Authorization", "Basic " & Base64Encode(":" & token)
http.setRequestHeader "Content-Type", "application/json"
http.send
' Check for HTTP errors
If http.Status <> 200 Then
jsonResponse = http.responseText
GoTo ErrorHandler
End If
' Parse JSON response
jsonResponse = http.responseText
Set json = JsonConverter.ParseJson(jsonResponse)
' Write data to worksheet
i = 1
For Each iteration In json("value")
ws.Cells(i, 1).Value = iteration("id")
ws.Cells(i, 2).Value = iteration("name")
ws.Cells(i, 3).Value = iteration("path")
ws.Cells(i, 4).Value = iteration("attributes")("startDate")
ws.Cells(i, 5).Value = iteration("attributes")("finishDate")
i = i + 1
Next iteration
' Format columns
ws.Columns("A:E").AutoFit
' Exit subroutine
Exit Sub
ErrorHandler:
Dim errorMessage As String
errorMessage = "Fout: " & Err.Number & " - " & Err.Description & vbCrLf & "Regel: " & Erl & vbCrLf & "Response: " & jsonResponse
' Write error message to cell B2 in "ErrorMessage" sheet
Dim errorSheet As Worksheet
On Error Resume Next
Set errorSheet = ThisWorkbook.Sheets("ErrorMessage")
If Not errorSheet Is Nothing Then
errorSheet.Cells(2, 2).Value = errorMessage
Else
MsgBox "Het werkblad 'ErrorMessage' bestaat niet.", vbCritical
End If
On Error GoTo 0
MsgBox errorMessage, vbCritical
Resume Next
End Sub
Function Base64Encode(text As String) As String
Dim arr() As Byte
arr = StrConv(text, vbFromUnicode)
Base64Encode = EncodeBase64(arr)
End Function
Function EncodeBase64(arr() As Byte) As String
Dim xml As Object
Set xml = CreateObject("MSXML2.DOMDocument")
xml.LoadXML "<root />"
xml.documentElement.dataType = "bin.base64"
xml.documentElement.nodeTypedValue = arr
EncodeBase64 = xml.documentElement.Text
End Function
I verified the correct functioning of the PAT by using Postman and Powershell. Both tools mentioned do retrieve the information I expected.
The URL I used I’ve verified with an web browsers Edge and Chrome. Below VBA code relies on an module published on Github, called JsonConverter.bas. The MS Excel version is an MS 365 app.
The current response on my request is below (I only shared an partial response due to the limitation of the number of characters allowed Response:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="nl-NL">
<head><title>
Azure DevOps Services | Sign In
</title><meta http-equiv="X-UA-Compatible" content="IE=11; IE=10; IE=9; IE=8" />
<link rel="SHORTCUT ICON" href="/favicon.ico"/>
<link data-bundlelength="516093" data-bundlename="commoncss" data-highcontrast="/_static/tfs/M251_20250210.1/_cssbundles/HighContrast/vss-bundle-commoncss-vgKIrce5KeykK4FMEhpmn7zyu-3J73Bx2KsJTMmi4ZaI=" data-includedstyles="jQueryUI-Modified;Core;Splitter;PivotView" href="/_static/tfs/M251_20250210.1/_cssbundles/Default/vss-bundle-commoncss-vuiSc9pHdDbcT8LzK_3fJ2kEsn4_fRqmPx_6IdU0oXHc=" rel="stylesheet" />
<link data-bundlelength="117396" data-bundlename="viewcss" data-highcontrast="/_static/tfs/M251_20250210.1/_cssbundles/HighContrast/vss-bundle-viewcss-vGUk8uw7JNxRjAw_tyNEzCFSNV6F4rpcB50TY_v1djOE=" data-includedstyles="VSS.Controls" href="/_static/tfs/M251_20250210.1/_cssbundles/Default/vss-bundle-viewcss-vKzCQ2wRcxozUbM0wmGy9QGeur1Tf6QGMY1-4Cznv5pQ=" rel="stylesheet" />
<!--UxServices customizations -->
<link href="/_static/tfs/M251_20250210.1/_content/Authentication.css" type="text/css" rel="stylesheet" />
</head>
<body class="platform">
As stated i can't get my head around this. I hope you can help me out.
Many thanks in advance.
You don't need to encode the Personal Access Token (PAT). Instead of using Basic
authentication, try using Bearer
authentication with the PAT directly as that in the Authorization
header below.
Sub GetADOIncrements()
On Error GoTo ErrorHandler
Dim http As Object
Dim url As String
Dim token As String
Dim jsonResponse As String
' Azure DevOps Organization and API URL
Dim organization As String
Dim project As String
organization = "YourAzureDevOpsOrgName" ' Replace with your organization
project = "Odin/FT" ' Replace with your project/Team
' Construct API URL
url = "https://dev.azure.com/" & organization & "/" & project & "/_apis/work/teamsettings/iterations?api-version=7.1"
' Personal Access Token (PAT)
token = "xxxxxx" ' Replace with your PAT
' Print API URL
Debug.Print "API URL: " & url
' Create HTTP request
Set http = CreateObject("MSXML2.ServerXMLHTTP")
http.Open "GET", url, False
http.setRequestHeader "Authorization", "Bearer " & token
http.setRequestHeader "Content-Type", "application/json"
http.send
' Check for HTTP errors
If http.Status <> 200 Then
jsonResponse = http.responseText
GoTo ErrorHandler
End If
' Print the raw API response
jsonResponse = http.responseText
Debug.Print "Response: " & jsonResponse
' Exit subroutine
Exit Sub
ErrorHandler:
Debug.Print "Error: " & Err.Number & " - " & Err.Description
Debug.Print "Response: " & jsonResponse
MsgBox "Error: " & Err.Number & " - " & Err.Description, vbCritical
End Sub