Una famiglia di software per fogli di calcolo Microsoft con strumenti per l'analisi, la creazione di grafici e la comunicazione dei dati.
Ciao Nicola,
Cit: Fammi sapere anche se l'allineamento errato della colonna delle risposte è l'unico problema che hai riscontrato.
Si Norman, questo è l'unico problema che ho incontrato su un **numero limitato ( sulla maggior parte funziona benissimo cambiando ogni volta il range dei dati e delle risposte giuste)**di file di Word mentre sul file chiamato: Ragionamento numerico (formattato come da immagine non da alcun risultato, ma no ho alcun messaggio di errore dal tuo codice).
Dato che la maggior parte dei file funzionano benissimo con il tuo codice, posto qui :
https://1drv.ms/f/s!Ali6qqOH3dOAjh_EDSD4CuLlspLm
i file di Word da sistemare e che non danno il risultato sperato.
Ho scaricato i tuoi due file.
Il secondo file illustra due caratteristiche particolarmente problematiche che sono state introdotte come risultato della conversione da Adobe del file PDF originale in un documento Word, ossia:
- Sporadicamente e casualmente, il documento di Word manca un carattere di interruzione di paragrafo alla fine di determinate righe. Ad esempio, nota la fine della riga evidenziata in blu:
Sfortunatamente, le interruzioni di paragrafo mancanti causano l'aggiunta delle righe pertinenti alla riga successiva e, di conseguenza, c'è una disparità tra l'elenco di domande e l'elenco di risposte corrispondente.
- Sporadicamente, nel caso di alcune pagine, la conversione in PDF di Adobe ha sovrapposto una riga di dati su una parte del piè di pagina, come si vede nel seguente screenshot:
- Sfortunatamente, quando il documento Word viene importato in Excel, i dati di sovrapposizione vengono persi.
Pertanto, ho modificato il codice di Word per inserire le interruzioni di paragrafo qualora fossero mancanti ed ho adattato il mio codice per riportare le risposte sempre sulle righe corrette. Inoltre, nel caso dei problemi relativi alla sovrapposizione di dati su alcuni piè di pagina, ho inserito una riga nella posizione richiesta delle domande, ho inserito il numero della domanda nella colonna A e, mediante un messagio alla conclusione del codice, Ho elencato le poche domande mancanti iin modo che tu potresti inserirle a mano.
Quindi, nel caso del file Capacit_ verbale.docx, il codice reporta tutte le domande con le richieste risposte e, per il secondo file, Ragionamento numerico.docx, il codice divide le righe coalescenti e elenca le domande mancanti dovuto ai problemi di sovrapposizione:
Quindi, sostituisci tutto il codice precedente con la seguente versione:
'=========>>
Option Explicit
Dim objWord As Word.Application
Dim WB As Workbook
Dim srcSH As Worksheet
Dim sFileName As String
Dim jCtr As Long
Dim arrMissing() As Variant
Const sFoglio As String = "Foglio1" '<<=== Modifica
'--------->>
Public Sub Tester()
Dim destSH As Worksheet
Dim rngDomande As Range, rngRisposte As Range
Dim arrIn As Variant, arrOut As Variant, arrOut2 As Variant
Dim arrRisposte As Variant
Dim sStr As String, sMsg As String, sTitle As String
Dim iButtons As Long
Const sIntervalloDomande As String = _
"A3:I1194" '<<=== Modifica
Const sIntervalloRisposte As String = _
"A1200:I1291" '<<=== Modifica
Set WB = ThisWorkbook
With WB
Set srcSH = .Sheets(sFoglio)
Set destSH = .Sheets.Add(After:=srcSH)
End With
On Error GoTo XIT
Application.ScreenUpdating = False
With srcSH
.Columns(1).Resize(5000).NumberFormat = "@"
Set rngDomande = .Range(sIntervalloDomande)
Set rngRisposte = .Range(sIntervalloRisposte)
End With
arrIn = rngDomande.Value
arrIn = JoinRows(arrIn)
arrIn = Compact_Columns(arrIn)
arrIn = Compact_Rows(arrIn)
arrOut = DeleteEmptyRows(arrIn)
arrOut = AddMissingQuestionRows(arrOut)
arrRisposte = rngRisposte.Value
arrRisposte = Riordina_ModificaRisposte(arrRisposte)
With destSH
.Range("A2").Resize(UBound(arrOut), 6).Value = arrOut
With .Range("A1").Offset(, 7). _
Resize(UBound(arrRisposte))
.NumberFormat = "@"
.Value = arrRisposte
End With
If Not sFileName = vbNullString Then
If Not SheetExists(sFileName) Then
.Name = sFileName
Else
Application.DisplayAlerts = False
WB.Sheets(sFileName).Delete
Application.DisplayAlerts = True
.Name = sFileName
End If
End If
End With
Call Format_Sheet(destSH)
If IsArrayAllocated(arrMissing) Then
sStr = Join(arrMissing, vbNewLine)
sMsg = "Le seguente domande non sono state " _
& "importate da Word." _
& vbNewLine & vbNewLine _
& "Controlla i piè di pagina pertinenti del " _
& "documento Word ed " _
& "inseririsci le domande mancanti a mano!" _
& vbNewLine & vbNewLine _
& sStr
sTitle = "CONTROLLA DOMANDE MANCANTI!"
iButtons = vbCritical
Else
sMsg = "Finito!"
sTitle = "REPORT"
iButtons = vbInformation
End If
Call MsgBox( _
Prompt:=sMsg, _
Buttons:=iButtons, _
Title:=sTitle)
XIT:
Application.ScreenUpdating = True
End Sub
'--------->>
Public Sub ImportWordToExcel()
Dim objDocument As Word.Document
Dim WB As Workbook
Dim SH As Worksheet
Dim Rng As Range
Dim varFiles As Variant
Dim strPath As String
Dim iFile As Long
Dim iNextRow As Long
Dim iCtr As Long
Application.ScreenUpdating = False
Set WB = ThisWorkbook
Set SH = WB.Sheets(sFoglio)
With SH
.Cells.ClearContents
Intersect(.Columns("B:I"), .Rows("1:5000")).NumberFormat = "@"
.DrawingObjects.Delete
.Cells(1, 1).Resize(3000).NumberFormat = "General"
End With
varFiles = Application.GetOpenFilename( _
"Word files (*.doc*),*.doc*", _
Title:="Seleziona i Files da copiare e importare.", _
MultiSelect:=True)
If TypeName(varFiles) = "Boolean" Then
Call MsgBox( _
Prompt:="Non hai selezionato un file Word da sviluppare", _
Buttons:=vbCritical, _
Title:="REPORT")
GoTo XIT
End If
Set objWord = New Word.Application
With objWord
.Visible = False
.DisplayAlerts = wdAlertsNone
.Options.CheckSpellingAsYouType = False
For iFile = LBound(varFiles) To UBound(varFiles)
iCtr = iCtr + 1
Application.StatusBar = "Sto lavorando il file nr: " _
& iCtr & " chiamato: " _
& strPath
DoEvents
Set objDocument = objWord.Documents.Open _
(varFiles(iFile))
With objDocument
strPath = .Name
sFileName = Split(strPath, ".")(0)
.SpellingChecked = True
Call BreakLines
.Content.Copy
With WB.Sheets("Foglio1")
.Activate
iNextRow = .Range("A100000").End(xlUp).Row + 1
.Range("A" & iNextRow).Select
.PasteSpecial Format:="HTML", _
Link:=False, _
DisplayAsIcon:=False, _
NoHTMLFormatting:=True
End With
DoEvents
Application.Wait (Now + TimeValue("0:00:10"))
objDocument.Close Savechanges:=wdDoNotSaveChanges
DoEvents
Set objDocument = Nothing
DoEvents
End With
Next iFile
.Quit
End With
Set objWord = Nothing
Call MsgBox( _
Prompt:="Ho terminato la copia dei dati con successo!" & _
vbNewLine & vbNewLine _
& "Sono stati importati " & iCtr _
& " files complessivamente!", _
Buttons:=vbInformation, _
Title:="WORD A EXCEL")
XIT:
With Application
.StatusBar = False
.ScreenUpdating = True
End With
End Sub
'--------->>
Public Sub BreakLines()
On Error GoTo XIT
Application.ScreenUpdating = False
With objWord
objWord.Selection.HomeKey unit:=wdStory
Do
.Selection.EndKey unit:=wdLine
If .Selection.End >= .ActiveDocument.Content.End - 1 Then
Exit Do
End If
If Asc(.Selection) <> 13 Then
.Selection.InsertParagraphAfter
End If
.Selection.MoveDown unit:=wdLine
Loop
End With
XIT:
Application.ScreenUpdating = True
End Sub
'--------->>
Public Function JoinRows(Arr As Variant)
Dim arrJoin() As Variant
Dim vVal As Variant
Dim aStr As String, sStr As String
Dim i As Long, j As Long, k As Long
Dim iDomanda As Long
For i = 2 To UBound(Arr, 2) - 1
For j = 2 To UBound(Arr) - 1
k = 0
vVal = Arr(j, 1)
If IsNumeric(vVal) And Not IsEmpty(vVal) Then
If vVal <= 356 Then
iDomanda = vVal
Do Until Arr(j + k, 1) > iDomanda
k = k + 1
sStr = Trim(Arr(j + k - 1, i))
Arr(j + k - 1, i) = Empty
ReDim Preserve arrJoin(1 To k)
arrJoin(k) = Trim(sStr)
Loop
aStr = Application.Trim(Join(arrJoin))
If aStr = vbNullString Then
Arr(j, i) = Empty
Else
Arr(j, i) = Application.Trim(Join(arrJoin))
End If
Erase arrJoin
j = j + k - 1
End If
End If
Next j
Next i
JoinRows = Arr
End Function
'--------->>
Public Function Compact_Columns(Arr As Variant) As Variant
Dim i As Long, j As Long, k As Long
Dim bHeaderRow As Boolean
bHeaderRow = True
For i = 1 To UBound(Arr)
For j = 2 To UBound(Arr, 2)
If IsEmpty(Arr(i, j)) Then
For k = j + 1 To UBound(Arr, 2)
If Not IsEmpty(Arr(i, k)) Then
Arr(i, j) = Arr(i, k)
Arr(i, k) = Empty
Exit For
End If
Next k
End If
Next j
Next i
Compact_Columns = Arr
End Function
'--------->>
Public Function Compact_Rows(Arr As Variant) As Variant
Dim i As Long, j As Long, k As Long
Dim bHeaderRow As Boolean
bHeaderRow = True
For i = 1 To UBound(Arr)
For j = 2 To UBound(Arr, 2)
If IsEmpty(Arr(i, j)) Or bHeaderRow Then
For k = j + 1 To UBound(Arr, 2)
If Not IsEmpty(Arr(i, k)) Then
Arr(i, j) = Arr(i, k)
Arr(i, k) = Empty
Exit For
End If
Next k
End If
Next j
bHeaderRow = False
Next i
Compact_Rows = Arr
End Function
'--------->
Public Function DeleteEmptyRows(Arr)
Dim arrOut As Variant
Dim i As Long, j As Long
Dim bHeaderRow As Boolean
ReDim arrOut(1 To UBound(Arr), 1 To 6)
bHeaderRow = True
jCtr = 0
For i = 1 To UBound(Arr)
If Application.IsNumber(Arr(i, 1)) Or bHeaderRow Then
jCtr = jCtr + 1
For j = 1 To 6
arrOut(jCtr, j) = Arr(i, j)
Next j
End If
bHeaderRow = False
Next i
DeleteEmptyRows = arrOut
End Function
'--------->
Public Function AddMissingQuestionRows(Arr)
Dim arrOut As Variant
Dim i As Long, j As Long
Dim iCtr As Long, jCtr As Long
Dim iUltimaDomanda As Long
Dim UB As Long, UB2 As Long
UB = UBound(Arr)
UB2 = UBound(Arr, 2)
With Application
iUltimaDomanda = .Max(.Index(Arr, 0, 1))
End With
ReDim arrOut(1 To iUltimaDomanda, 1 To UB2)
For i = 2 To iUltimaDomanda + 1
iCtr = iCtr + 1
For j = 1 To UB2
arrOut(iCtr, j) = Arr(i, j)
Next j
If iCtr < iUltimaDomanda Then
If Arr(i + 1, 1) <> Arr(i, 1) + 1 Then
'\ Salta riga
iCtr = iCtr + 1
arrOut(iCtr, 1) = iCtr
'\ Carica arrMissing con il numero della
'\ domanda non riportata da Word
jCtr = jCtr + 1
ReDim Preserve arrMissing(1 To jCtr)
arrMissing(jCtr) = iCtr
End If
End If
If iCtr = iUltimaDomanda Then
Exit For
End If
Next i
XIT:
AddMissingQuestionRows = arrOut
End Function
'--------->>
Public Function Riordina_ModificaRisposte(Arr As Variant) As Variant
Dim arrOut As Variant
Dim i As Long, j As Long, k As Long
Dim vVal As Variant
Dim iHour As Long
Dim UB As Long, UB2 As Long
UB = UBound(Arr)
UB2 = UBound(Arr, 2)
ReDim arrOut(1 To UB * UB2 + 1, 1 To 1)
arrOut(1, 1) = "Risposta Giusta"
k = 1
For i = 1 To UB2
For j = 1 To UB
vVal = Arr(j, i)
If Not IsEmpty(vVal) Then
k = k + 1
If Not IsEmpty(vVal) And IsNumeric(vVal) Then
iHour = Hour(vVal)
vVal = "'" & iHour & " A"
End If
arrOut(k, 1) = vVal
End If
Next j
Next i
Riordina_ModificaRisposte = arrOut
End Function
'--------->>
Public Sub Format_Sheet(aSH As Worksheet)
Dim arrColWidths As Variant
Dim arrHeaders As Variant
Dim i As Long
Const sColWidths As String = "8,54,30,30,30,30,4,12"
Const sHeaders As String = "N.,Domanda,A,B,C,D"
arrColWidths = Split(sColWidths, ",")
arrHeaders = Split(sHeaders, ",")
With aSH
For i = 1 To UBound(arrColWidths) + 1
.Columns(i).ColumnWidth = arrColWidths(i - 1)
Next i
.Range("A1").Resize(1, UBound(arrHeaders) + 1).Value = _
arrHeaders
With .UsedRange
.WrapText = True
.VerticalAlignment = xlCenter
.IndentLevel = 2
.EntireRow.AutoFit
End With
End With
End Sub
'--------->>
Function IsArrayAllocated(Arr As Variant) As Boolean
On Error Resume Next
IsArrayAllocated = IsArray(Arr) And _
Not IsError(LBound(Arr, 1)) And _
LBound(Arr, 1) <= UBound(Arr, 1)
End Function
'--------->>
Public Function SheetExists(sSheetName As String, _
Optional ByVal WB As Workbook) As Boolean
On Error Resume Next
If WB Is Nothing Then
Set WB = ThisWorkbook
End If
SheetExists = CBool(Len(WB.Sheets(sSheetName).Name))
On Error GoTo 0
End Function
'<<=========
===
Regards,
Norman