Public oInstance As MSXML2.DOMDocument60 Public m_InstanceURI As String Public m_strUSGAAP_TaxonomyVersion As String Public m_strInvest_TaxonomyVersion As String Public m_strDEI_TaxonomyVersion As String Public m_strContextForInstants As String Public m_strContextForDurations As String Public m_BalanceSheetDate As String Public m_IncomeStatementPeriodYTD As String Public m_DocumentPeriodEndDate As String Public m_DocumentPeriodEndDate_ContextID As String Public m_DocumentPeriodEndDate_startDate As String Public m_DocumentPeriodEndDate_endDate As String Public strEntityRegistrantName As String Public strEntityCentralIndexKey As String Public strEntityFilerCategory As String Public strTradingSymbol As String Public strCompanyFiscalYearEnd As String Public strFiscalYearFocus As String Public strFiscalPeriodFocus As String Public strDocumentType As String Public strBalanceSheetFormat As String Public strIncomeStatementFormat As String Public strAssets As String Public strLiabilitiesAndEquity As String Public strBalanceSheetBalances As String Public strInterestIncomeExpenseOperatingNet As String Function Test() ProcessXBRLInstance "http://www.sec.gov/Archives/edgar/data/1060219/000155479515000335/sal-20150630.xml" End Function Sub ProcessXBRLInstance(strXBRLInstanceLocation As String) On Error GoTo ErrorHandler m_InstanceURI = strXBRLInstanceLocation 'Load XBRL instance into memory LoadXBRLInstanceIntoMemory strXBRLInstanceLocation 'Load base information and period information GetBaseInformation GetCurrentPeriodAndContextInformation GetBalanceSheetBalances GetIncomeStatementInformation 'Print information to debug window Debug.Print "SUMMARY INFORMATION:" Debug.Print "XBRL instance : " & strXBRLInstanceLocation Debug.Print "SEC Filing Page : http://www.sec.gov/Archives/edgar/data/" Debug.Print "XBRL Cloud Viewer : https://edgardashboard.xbrlcloud.com/flex/viewer/XBRLViewer.html#instance=" & strXBRLInstanceLocation Debug.Print " " Debug.Print "US GAAP Taxonomy version : " & m_strUSGAAP_TaxonomyVersion Debug.Print "DEI Taxonomy version : " & m_strDEI_TaxonomyVersion Debug.Print " " Debug.Print "Entity registrant name : " & strEntityRegistrantName Debug.Print "CIK : " & strEntityCentralIndexKey Debug.Print "Entity filer category : " & strEntityFilerCategory Debug.Print "Trading symbol : " & strTradingSymbol Debug.Print "Company fiscal year end : " & strCompanyFiscalYearEnd Debug.Print "Fiscal year focus : " & strFiscalYearFocus Debug.Print "Fiscal period focus : " & strFiscalPeriodFocus Debug.Print "Document type : " & strDocumentType Debug.Print " " Debug.Print "Current balance sheet date: " & m_BalanceSheetDate Debug.Print "Current YTD income stmt: : " & m_IncomeStatementPeriodYTD & " to " & m_BalanceSheetDate Debug.Print " " Debug.Print "Document period end date (DPED information)" Debug.Print "DPED value : " & m_BalanceSheetDate Debug.Print "DPED context ID : " & m_DocumentPeriodEndDate_ContextID Debug.Print "DPED context endDate : " & m_DocumentPeriodEndDate_endDate Debug.Print "DPED context startDate : " & m_DocumentPeriodEndDate_startDate Debug.Print " " Debug.Print "Context ID for as of : " & m_strContextForInstants & " (instants)" Debug.Print "Context ID for for period : " & m_strContextForDurations & " (durations)" Debug.Print " " Debug.Print "Assets : " & strAssets Debug.Print "Liabilities and equity : " & strLiabilitiesAndEquity Debug.Print "Balance sheet balances : " & strBalanceSheetBalances Debug.Print " " Debug.Print " " Debug.Print "Interest Income (Expense) Operating, Net : " & strInterestIncomeExpenseOperatingNet Debug.Print " " Exit Sub ErrorHandler: If Err.Number <> 91 Or Err.Number <> 6 Or Err.Number <> 11 Then 'Debug.Print "Error number " & Err.Number & ": " & Err.Description Resume Next End If End Sub Function GetFactValue(strSeekConcept As String, strConceptPeriodType As String) As String On Error GoTo ErrorHandler GetFactValue = "NOT-FOUND" 'Determine which context to use (instant or duration) Dim strContextReference As String If strConceptPeriodType = "Instant" Then 'Concept is an instance strContextReference = m_strContextForInstants ElseIf strConceptPeriodType = "Duration" Then 'Concept is a duration strContextReference = m_strContextForDurations Else 'An error occured GetFactValue = "CONTEXT ERROR" Exit Function End If Set oNodeList = oInstance.selectNodes("//" & strSeekConcept & "[@contextRef='" & strContextReference & "']") 'MsgBox strSeekConcept & " " & oNodeList.length If oNodeList.length > 0 Then GetFactValue = oInstance.selectSingleNode("//" & strSeekConcept & "[@contextRef='" & strContextReference & "']").Text 'If the concept exists and @nil is true, set the value to 0 If oInstance.selectSingleNode("//" & strSeekConcept & "[@contextRef='" & strContextReference & "']/@xsi:nil").Text = "true" Then 'Set the value to ZERO if it is nil GetFactValue = 0 End If End If Exit Function ErrorHandler: If Err.Number <> 91 Then Debug.Print "Error number " & Err.Number & ": " & Err.Description Resume Next End If End Function Private Function LoadXBRLInstanceIntoMemory(strInstanceLocation As String) On Error GoTo ErrorHandler Set oInstance = Nothing Set oInstance = New MSXML2.DOMDocument60 oInstance.async = False oInstance.validateOnParse = False oInstance.Load (strInstanceLocation) DoEvents If oInstance.parseError.ErrorCode <> 0 Then Debug.Print "Error loading file: " & vbCrLf & vbCrLf & _ "File URL: " & oInstance.parseError.url & vbCrLf & _ "Error Code: " & oInstance.parseError.ErrorCode & vbCrLf & _ "Error Description: " & oInstance.parseError.reason & vbCrLf _ , vbCritical End If 'The XBRL instance is loaded into memory as a global variable and now can be accessed 'MsgBox "File loaded: " & strInstanceLocation & " " & vbCrLf & vbCrLf & oInstance.XML Exit Function ErrorHandler: If Err.Number <> 91 Then Debug.Print "Error number " & Err.Number & ": " & Err.Description Resume Next End If End Function Private Sub GetBaseInformation() On Error GoTo ErrorHandler 'This gets the taxonomy version m_strContextForInstants = "ERROR" m_strContextForDurations = "ERROR" 'Taxonomy version (Figures out which version of taxonomy is being used) Dim strEntireInstanceDocument_TEMP As String Dim strTaxonomyVersion As String Dim strUSGAAP_TaxonomyVersion As String Dim strDEI_TaxonomyVersion As String strEntityRegistrantName = "ERROR" strTaxonomyVersion = "ERROR" strUSGAAP_TaxonomyVersion = "ERROR" strDEI_TaxonomyVersion = "ERROR" 'This differentiates between the 2015, 2014, 2013, 2012, 2011, and 2009 US GAAP taxonomies... 'Brute force method for finding the namespaces (text search of XML) strEntireInstanceDocument_TEMP = oInstance.XML '0=not found; 'US GAAP Taxonomy If InStr(1, strEntireInstanceDocument_TEMP, "http://fasb.org/us-gaap/2015-01-31") <> 0 Then 'Uses the 2015 US GAAP taxonomy m_strUSGAAP_TaxonomyVersion = "http://fasb.org/us-gaap/2015-01-31" m_strInvest_TaxonomyVersion = "http://xbrl.sec.gov/invest/2014-01-31" End If If InStr(1, strEntireInstanceDocument_TEMP, "http://fasb.org/us-gaap/2014-01-31") <> 0 Then 'Uses the 2014 US GAAP taxonomy m_strUSGAAP_TaxonomyVersion = "http://fasb.org/us-gaap/2014-01-31" m_strInvest_TaxonomyVersion = "http://xbrl.sec.gov/invest/2014-01-31" End If If InStr(1, strEntireInstanceDocument_TEMP, "http://fasb.org/us-gaap/2013-01-31") <> 0 Then 'Uses the 2013 US GAAP taxonomy m_strUSGAAP_TaxonomyVersion = "http://fasb.org/us-gaap/2013-01-31" m_strInvest_TaxonomyVersion = "http://xbrl.sec.gov/invest/2013-01-31" End If If InStr(1, strEntireInstanceDocument_TEMP, "http://fasb.org/us-gaap/2012-01-31") <> 0 Then 'Uses the 2012 US GAAP taxonomy m_strUSGAAP_TaxonomyVersion = "http://fasb.org/us-gaap/2012-01-31" m_strInvest_TaxonomyVersion = "http://xbrl.sec.gov/invest/2012-01-31" End If If InStr(1, strEntireInstanceDocument_TEMP, "http://fasb.org/us-gaap/2011-01-31") <> 0 Then 'Uses the 2011 US GAAP taxonomy m_strUSGAAP_TaxonomyVersion = "http://fasb.org/us-gaap/2011-01-31" m_strInvest_TaxonomyVersion = "http://xbrl.sec.gov/invest/2011-01-31" End If If InStr(1, strEntireInstanceDocument_TEMP, "http://xbrl.us/us-gaap/2009-01-31") <> 0 Then 'Uses the 2009 US GAAP taxonomy m_strUSGAAP_TaxonomyVersion = "http://xbrl.us/us-gaap/2009-01-31" m_strInvest_TaxonomyVersion = "http://xbrl.us/invest/2019-01-31" End If 'DEI Taxonomy If InStr(1, strEntireInstanceDocument_TEMP, "http://xbrl.sec.gov/dei/2014-01-31") <> 0 Then 'Uses the 2014 DEI taxonomy m_strDEI_TaxonomyVersion = "http://xbrl.sec.gov/dei/2014-01-31" End If If InStr(1, strEntireInstanceDocument_TEMP, "http://xbrl.sec.gov/dei/2013-01-31") <> 0 Then 'Uses the 2013 DEI taxonomy m_strDEI_TaxonomyVersion = "http://xbrl.sec.gov/dei/2013-01-31" End If If InStr(1, strEntireInstanceDocument_TEMP, "http://xbrl.sec.gov/dei/2012-01-31") <> 0 Then 'Uses the 2012 DEI taxonomy m_strDEI_TaxonomyVersion = "http://xbrl.sec.gov/dei/2012-01-31" End If If InStr(1, strEntireInstanceDocument_TEMP, "http://xbrl.sec.gov/dei/2011-01-31") <> 0 Then 'Uses the 2011 DEI taxonomy m_strDEI_TaxonomyVersion = "http://xbrl.sec.gov/dei/2011-01-31" End If If InStr(1, strEntireInstanceDocument_TEMP, "http://xbrl.us/dei/2009-01-31") <> 0 Then 'Uses the 2009 DEI taxonomy m_strDEI_TaxonomyVersion = "http://xbrl.us/dei/2009-01-31" End If 'Sets the namespaces for the XML document oInstance.SetProperty "SelectionNamespaces", "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xbrli='http://www.xbrl.org/2003/instance' xmlns='http://www.xbrl.org/2003/instance' xmlns:xbrldi='http://xbrl.org/2006/xbrldi' xmlns:us-gaap='" & m_strUSGAAP_TaxonomyVersion & "' xmlns:dei='" & m_strDEI_TaxonomyVersion & "' xmlns:currency='http://xbrl.sec.gov/currency/2012-01-31' xmlns:invest='" & m_strInvest_TaxonomyVersion & "'" 'Variables used Dim oNodeList As MSXML2.IXMLDOMNodeList Dim strSeekConcept As String 'Registered Name (required, exists only once) strEntityRegistrantName = oInstance.selectSingleNode("//dei:EntityRegistrantName").Text 'EntityCentralIndexKey (required, exists only once) strEntityCentralIndexKey = oInstance.selectSingleNode("//dei:EntityCentralIndexKey").Text 'EntityFilerCategory (required, but a few filers don't provide) strEntityFilerCategory = oInstance.selectSingleNode("//dei:EntityFilerCategory").Text 'Company fiscal year end (required) strCompanyFiscalYearEnd = oInstance.selectSingleNode("//dei:CurrentFiscalYearEndDate").Text 'FiscalYearFocus (required) strFiscalYearFocus = oInstance.selectSingleNode("//dei:DocumentFiscalYearFocus").Text 'FiscalPeriodFocus (required) strFiscalPeriodFocus = oInstance.selectSingleNode("//dei:DocumentFiscalPeriodFocus").Text 'DocumentType (required, but a few filers don't provide) strDocumentType = oInstance.selectSingleNode("//dei:DocumentType").Text 'TradingSymbol(optional) Set oNodeList = oInstance.selectNodes("//dei:TradingSymbol[@contextRef]") 'MsgBox oNodeList.length If oNodeList.length > 0 Then strTradingSymbol = oInstance.selectSingleNode("//dei:TradingSymbol").Text Else strTradingSymbol = "Not provided" End If Exit Sub ErrorHandler: If Err.Number <> 91 Then Debug.Print "Error number " & Err.Number & ": " & Err.Description End If Resume Next End Sub Private Sub GetCurrentPeriodAndContextInformation() 'Figures out the current period and contexts for the current period instance/duration contexts On Error GoTo ErrorHandler m_BalanceSheetDate = "ERROR" m_IncomeStatementPeriodYTD = "ERROR" m_strContextForInstants = "ERROR" m_strContextForDurations = "ERROR" m_DocumentPeriodEndDate = "ERROR" m_DocumentPeriodEndDate_ContextID = "ERROR" m_DocumentPeriodEndDate_startDate = "ERROR" m_DocumentPeriodEndDate_endDate = "ERROR" 'Get the value of the dei:DocumentPeriodEndDate m_DocumentPeriodEndDate = oInstance.selectSingleNode("//dei:DocumentPeriodEndDate").Text 'Get the context ID of the dei:DocumentPeriodEndDate m_DocumentPeriodEndDate_ContextID = oInstance.selectSingleNode("//dei:DocumentPeriodEndDate/@contextRef").Text 'Get the end date of the context for the fact dei:DocumentPeriodEndDate m_DocumentPeriodEndDate_endDate = oInstance.selectSingleNode("//xbrli:context[@id='" & oInstance.selectSingleNode("//dei:DocumentPeriodEndDate/@contextRef").Text & "']/xbrli:period/xbrli:endDate").Text 'Get the start date of the context for the fact dei:DocumentPeriodEndDate m_DocumentPeriodEndDate_startDate = oInstance.selectSingleNode("//xbrli:context[@id='" & oInstance.selectSingleNode("//dei:DocumentPeriodEndDate/@contextRef").Text & "']/xbrli:period/xbrli:startDate").Text 'Look through all the instant contexts for the context which 'is the current balance sheed date context and get the context ID: Dim oNode As IXMLDOMNode Dim oNodeList As IXMLDOMNodeList Set oNodeList = oInstance.selectNodes("//xbrli:context[xbrli:period/xbrli:instant][not(xbrli:entity/xbrli:segment)]") 'MsgBox oNodeList.Length For Each oNode In oNodeList Dim strContextInstantValue As String strContextInstantValue = oNode.selectSingleNode("xbrli:period/xbrli:instant").Text Dim strMatchingID As String strMatchingID = "NO-MATCH" If strContextInstantValue = m_DocumentPeriodEndDate_endDate Then 'MsgBox "Match: " & oNode.SelectSingleNode("@id").Text strMatchingID = oNode.selectSingleNode("@id").Text Exit For End If Next m_BalanceSheetDate = m_DocumentPeriodEndDate_endDate m_strContextForInstants = strMatchingID m_IncomeStatementPeriodYTD = m_DocumentPeriodEndDate_startDate m_strContextForDurations = oInstance.selectSingleNode("//dei:DocumentPeriodEndDate/@contextRef").Text Exit Sub ErrorHandler: If Err.Number <> 91 Then Debug.Print "Error number " & Err.Number & ": " & Err.Description End If Resume Next End Sub Private Sub GetBalanceSheetBalances() 'Balance sheet balances strAssets = "ERROR" strLiabilitiesAndEquity = "ERROR" strBalanceSheetBalances = "ERROR" strAssets = GetFactValue("us-gaap:Assets", "Instant") strLiabilitiesAndEquity = GetFactValue("us-gaap:LiabilitiesAndStockholdersEquity", "Instant") strBalanceSheetBalances = CDbl(strAssets) - CDbl(strLiabilitiesAndEquity) Exit Sub ErrorHandler: If Err.Number <> 91 Then Debug.Print "Error number " & Err.Number & ": " & Err.Description End If Resume Next End Sub Private Sub GetIncomeStatementInformation() 'Balance sheet balances strInterestIncomeExpenseOperatingNet = "ERROR" strInterestIncomeExpenseOperatingNet = GetFactValue("us-gaap:InterestIncomeExpenseNet", "Duration") Exit Sub ErrorHandler: If Err.Number <> 91 Then Debug.Print "Error number " & Err.Number & ": " & Err.Description End If Resume Next End Sub Function RunProof() On Error GoTo ErrorHandler DoCmd.SetWarnings False DoCmd.RunSQL "DELETE * FROM Proof" DoCmd.SetWarnings True Dim rsADD As Recordset Set rsADD = CurrentDb().OpenRecordset("SELECT * from Proof") Dim rs As Recordset Set rs = CurrentDb().OpenRecordset("SELECT * from InternalDashboard") Debug.Print "Begin process: " Do While Not rs.EOF DoEvents Debug.Print rs.AbsolutePosition & " " & rs!EntityRegistrantName 'This uses XBRL Cloud Cached copy... Dim strLinkToXBRLInstance_Temp As String strLinkToXBRLInstance_Temp = rs!LinkToXBRLInstance ProcessXBRLInstance strLinkToXBRLInstance_Temp DoEvents rsADD.AddNew rsADD!LinkToXBRLInstance = rs!LinkToXBRLInstance rsADD!Assets = CDbl(strAssets) rsADD!LiabilitiesAndEquity = CDbl(strLiabilitiesAndEquity) rsADD!BalanceSheetBalances = CDbl(strAssets) - CDbl(strLiabilitiesAndEquity) rsADD!InterestIncomeExpenseOperatingNet = CDbl(strInterestIncomeExpenseOperatingNet) rsADD!DocumentPeriodEndDate_Value = m_DocumentPeriodEndDate rsADD!DocumentPeriodEndDate_ContextEndDateValue = m_DocumentPeriodEndDate_endDate rsADD!DPED_Consistency = IIf(m_DocumentPeriodEndDate_endDate = m_DocumentPeriodEndDate, "Consistent", "Inconsistent") rsADD!EntityRegistrantName = strEntityRegistrantName rsADD!CIK = strEntityCentralIndexKey rsADD!EntityFilerCategory = strEntityFilerCategory rsADD!FiscalYearFocus = strFiscalYearFocus rsADD!FiscalPeriodFocus = strFiscalPeriodFocus rsADD!DocumentType = strDocumentType rsADD!USGAAPTaxonomyVersion = m_strUSGAAP_TaxonomyVersion rsADD!DEITaxonomyVersion = m_strDEI_TaxonomyVersion rsADD!FilerFiscalYear = strCompanyFiscalYearEnd rsADD.Update rs.MoveNext Loop Debug.Print "Process compete!" Exit Function ErrorHandler: If Err.Number <> 91 Then Debug.Print "Error number " & Err.Number & ": " & Err.Description End If Resume Next End Function