You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

拆分Excel上传SharePoint时遇未授权错误求助

问题:VBA拆分Excel后上传SharePoint遇未授权错误

我使用VBA代码将一份Excel文件按「Owner」列拆分为多个独立Excel文件,再上传至SharePoint。执行过程中会弹出凭证输入窗口,但输入凭证后仍抛出**unauthorized(未授权)**错误。

实现代码

Private Sub CommandButton1_Click()
Dim ws As Worksheet
Dim tbl As ListObject
Dim lastRow As Long
Dim uniqueValues As Collection
Dim value As Variant
Dim newWorkbook As Workbook
Dim savePath As String
Dim headerToFilter As String
Dim headersToUnlock As Variant
Dim headerIndexFilter As Long
Dim headerIndexUnlock As Variant
Dim headerRange As Range
Dim fileName As String
Dim SPUrl As String
Dim SPFolder As String
Dim SPUsername As String
Dim SPPassword As String
Dim HTTPReq As Object

' Set SharePoint credentials and URLs
SPUrl = "https://mycompanysharepoint/:f:/s/TreasuryTransformation/"
SPFolder = "Shared%20Documents/General/PO%20Accrual/Excel%20to%20split" ' Path to the SharePoint document library folder
SPUsername = "myemailid@compamanydomain"
SPPassword = "password"
 
' Set the worksheet you want to process
Set ws = ThisWorkbook.Sheets("OpenPO") ' Replace "Sheet1" with your sheet name
Set splitws = ThisWorkbook.Sheets("Split excel")

' Set the table name you want to process
On Error Resume Next
Set tbl = ws.ListObjects("OpenPO") ' Replace "TableName" with your table name
On Error GoTo 0
If tbl Is Nothing Then
    MsgBox "Table 'OpenPO' not found!"
    Exit Sub
End If

' Set the header name you want to filter on
headerToFilter = "Owner" ' Replace "HeaderToFilter" with your header name for filtering
 
' Find the column index of the header to filter
On Error Resume Next
headerIndexFilter = tbl.ListColumns(headerToFilter).Index
On Error GoTo 0
If headerIndexFilter = 0 Then
    MsgBox "Header '" & headerToFilter & "' not found in the table!"
    Exit Sub
End If
 
' Check if there is data in the table
If tbl.DataBodyRange Is Nothing Then
    MsgBox "No data found in the table!"
    Exit Sub
End If

'Check if the filter column contains any Excel Error'
Dim cell As Range
For Each cell In tbl.ListColumns(headerIndexFilter).DataBodyRange
    If IsError(cell.value) Then
        MsgBox "Column '" & headerToFilter & "' contains Excel errors. Please Fix them and try again."
        Exit Sub
    ElseIf Application.WorksheetFunction.CountIf(tbl.ListColumns(headerIndexFilter).DataBodyRange, 0) > 0 Then
        MsgBox "Column '" & headerToFilter & "' has 0 in place of owner name. Please Fix them and try again."
        Exit Sub
    End If
Next cell
 
' Set the header names for columns to unlock
headersToUnlock = Array("Comment - Reporting Team", "Correction Journal Name") ' Replace with your header names to unlock
 
' Find the column indexes for headers to unlock
ReDim headerIndexUnlock(LBound(headersToUnlock) To UBound(headersToUnlock))
For i = LBound(headersToUnlock) To UBound(headersToUnlock)
    Set headerRange = tbl.HeaderRowRange.Find(headersToUnlock(i), LookIn:=xlValues, LookAt:=xlWhole)
    If Not headerRange Is Nothing Then
        headerIndexUnlock(i) = headerRange.Column
         MsgBox "Header '" & headersToUnlock(i) & "' found! at '" & headerRange.Column & "'"
    Else
        MsgBox "Header '" & headersToUnlock(i) & "' not found!"
        Exit Sub
    End If
Next i
 
' Get the last row of data in the table
lastRow = tbl.DataBodyRange.Rows.Count
 
' Create a collection to store unique values from the specified column
Set uniqueValues = New Collection
 
' Loop through the data and collect unique values
On Error Resume Next
For i = 1 To lastRow
    If tbl.DataBodyRange.Cells(i, headerIndexFilter).value <> "" Then
        uniqueValues.Add tbl.DataBodyRange.Cells(i, headerIndexFilter).value, CStr(tbl.DataBodyRange.Cells(i, headerIndexFilter).value)
    End If
Next i
On Error GoTo 0
 
' Loop through unique values and create separate workbooks
For Each value In uniqueValues
    If value <> "" Then
        ' Filter data based on unique values
        tbl.Range.AutoFilter Field:=headerIndexFilter, Criteria1:=value
 
        ' Copy visible cells to a new workbook
        Set newWorkbook = Workbooks.Add
        tbl.HeaderRowRange.Copy Destination:=newWorkbook.Sheets(1).Range("A1")
        tbl.DataBodyRange.SpecialCells(xlCellTypeVisible).Copy
        newWorkbook.Sheets(1).Range("A2").PasteSpecial Paste:=xlPasteValues ' Copy filtered data starting from row 2
        Application.CutCopyMode = False 'Clear clipboard
        
        ' Apply formatting
        With newWorkbook.Sheets(1)
            .Range("A1").CurrentRegion.Columns.AutoFit
            .Range("A1").CurrentRegion.Borders.LineStyle = xlContinuous
            .Range("A1").CurrentRegion.Font.Bold = True
        End With
        
        ' Unfilter the original data
        tbl.Range.AutoFilter Field:=headerIndexFilter
        
        ' Lock all cells by default
            newWorkbook.Sheets(1).Cells.Locked = True

            ' Unlock specific columns
            For Each headerIndexUnlockValue In headerIndexUnlock
                newWorkbook.Sheets(1).Columns(headerIndexUnlockValue).Locked = False
            Next headerIndexUnlockValue

            ' Protect the sheet
            newWorkbook.Sheets(1).Protect Password:="test", UserInterfaceOnly:=True

            ' Generate dynamic file name with date and time
            fileName = "Split_" & value & "_" & Format(Now, "yyyy-mm-dd_hh-mm-ss") & ".xlsx"

            ' Set the save path and filename
            savePath = Environ("TEMP") & "\" & fileName ' Temporary path with dynamic file name

            ' Save the new workbook temporarily
            newWorkbook.SaveAs savePath
            newWorkbook.Close SaveChanges:=False
            
           
            ' Upload file to SharePoint
            Set HTTPReq = CreateObject("MSXML2.XMLHTTP")
            HTTPReq.Open "PUT", SPUrl & "/_api/web/GetFolderByServiceRelativeUrl('" & SPFolder & "')/Files/Add(url='" & fileName & "', overwrite=true)", False
            HTTPReq.setRequestHeader "Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
            HTTPReq.setRequestHeader "X-FORMS_BASED_AUTH_ACCEPTED", "f"
            HTTPReq.setRequestHeader "Authorization", "Basic " & Base64Encode(SPUsername & ":" & SPPassword)

            ' Open the file to be uploaded
            Dim fileStream As Object
            Set fileStream = CreateObject("ADODB.Stream")
            fileStream.Open
            fileStream.Type = 1 ' Binary
            fileStream.LoadFromFile savePath

            ' Send the request to upload the file
            HTTPReq.Send fileStream.Read

            ' Check if the upload was successful
            If HTTPReq.Status = 200 Then
                MsgBox "File uploaded successfully to SharePoint."
            Else
                MsgBox "Error uploading file to SharePoint: " & HTTPReq.statusText
                Exit Sub
            End If

            ' Clean up
            fileStream.Close
            Set fileStream = Nothing
            Set HTTPReq = Nothing

            ' Delete the temporary file
            Kill savePath
    End If
Next value

MsgBox "Split and upload operation completed successfully!"
End Sub

    Private Function Base64Encode(ByVal sText As String) As String
Dim arrData() As Byte
arrData = StrConv(sText, vbFromUnicode)
Dim objXML As Object
Dim objNode As Object
Set objXML = CreateObject("MSXML2.DOMDocument")
Set objNode = objXML.createElement("b64")
objNode.DataType = "bin.base64"
objNode.nodeTypedValue = arrData
Base64Encode = objNode.Text
Set objNode = Nothing
Set objXML = Nothing
End Function

代码执行流程

  • 指定SharePoint凭证与目标路径
  • 检查目标表格是否存在、数据是否合法(无错误值、无无效Owner)
  • 提取Owner列的唯一值,为每个值生成独立Excel文件
  • 设置工作表保护:默认锁定所有单元格,仅指定列可编辑
  • 临时保存文件后,通过SharePoint REST API上传文件

凭证输入弹窗

凭证输入弹窗

内容的提问来源于stack exchange,提问作者Apoorv Jain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 11:59:49