Загрузка данных
' ===== В САМОМ ВЕРХУ МОДУЛЯ (Personal.xlsb) =====
Private SavedRow As Long
Private SavedCol As Long
Private SavedNumLines As Long
Private SavedOldData As Variant
' =================================================
Sub ВставитьСписокИзWordСНумерацией()
Dim dataObj As Object, clipText As String, linesArr As Variant
Dim i As Long, lineText As String, numPart As String, textPart As String
Dim dotPos As Long, totalLines As Long
Dim ws As Worksheet
Dim rngBefore As Range
' 1. Читаем буфер обмена
On Error Resume Next
Set dataObj = CreateObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
If Err.Number <> 0 Then
On Error GoTo 0
Set dataObj = CreateObject("MSForms.DataObject")
End If
On Error GoTo 0
If dataObj Is Nothing Then
MsgBox "Не удалось получить доступ к буферу обмена.", vbExclamation
Exit Sub
End If
dataObj.GetFromClipboard
clipText = dataObj.GetText
If Len(Trim(clipText)) = 0 Then
MsgBox "Буфер обмена пуст или содержит не текст.", vbInformation
Exit Sub
End If
' 2. Разбиваем на строки
linesArr = Split(clipText, vbCrLf)
If UBound(linesArr) < 0 Then linesArr = Split(clipText, vbLf)
' Убираем возможную пустую последнюю строку
Dim ub As Long
ub = UBound(linesArr)
If ub >= 0 Then
If Len(Trim(linesArr(ub))) = 0 Then
ub = ub - 1
End If
End If
If ub < 0 Then
MsgBox "Не найдено ни одной строки текста.", vbInformation
Exit Sub
End If
' 3. Определяем заголовок и элементы
Dim headerText As String
headerText = linesArr(0)
Dim itemLines() As String
Dim numItems As Long
If ub >= 1 Then
numItems = ub ' строки с 1 по ub – элементы
ReDim itemLines(0 To numItems - 1)
For i = 0 To numItems - 1
itemLines(i) = linesArr(i + 1)
Next i
Else
numItems = 0
End If
totalLines = 1 + numItems
' 4. Сохраняем состояние ячеек C:F
Set ws = ActiveSheet
SavedRow = ActiveCell.Row
SavedCol = 3 ' столбец C
SavedNumLines = totalLines
Set rngBefore = ws.Range(ws.Cells(SavedRow, 3), ws.Cells(SavedRow + totalLines - 1, 6))
If Not rngBefore Is Nothing Then
SavedOldData = rngBefore.Value
Else
SavedOldData = Empty
End If
' 5. Вставляем строки
Application.ScreenUpdating = False
ws.Rows(SavedRow & ":" & SavedRow + totalLines - 1).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
' 6. Вставляем заголовок: объединяем C и D
With ws.Range(ws.Cells(SavedRow, 3), ws.Cells(SavedRow, 4))
.Merge
.Value = headerText
.Font.Bold = False
End With
' 7. Вставляем элементы списка
For i = 0 To numItems - 1
lineText = itemLines(i)
' Разбиваем строку по табуляции
Dim parts As Variant
parts = Split(lineText, vbTab)
' Проверка на случай пустого массива (практически никогда, но для безопасности)
If Not IsArray(parts) Then
MsgBox "Внутренняя ошибка: Split не вернул массив для строки " & i + 1, vbExclamation
GoTo NextItem
End If
If UBound(parts) < 0 Then
MsgBox "Пустая строка (без данных) в строке " & i + 1 & ". Пропущено.", vbExclamation
GoTo NextItem
End If
Dim mainPart As String, extra1 As String, extra2 As String
mainPart = Trim(parts(0))
extra1 = ""
extra2 = ""
If UBound(parts) >= 1 Then extra1 = Trim(parts(1))
If UBound(parts) >= 2 Then extra2 = Trim(parts(2))
' Извлекаем номер и текст из основной части
dotPos = InStr(mainPart, ". ")
If dotPos > 0 And IsNumeric(Left(mainPart, dotPos - 1)) Then
numPart = Left(mainPart, dotPos + 1) ' "1. "
textPart = Trim(Mid(mainPart, dotPos + 2))
Else
numPart = ""
textPart = mainPart
End If
Dim currentRow As Long
currentRow = SavedRow + 1 + i
' C: номер
With ws.Cells(currentRow, 3)
.Value = numPart
.Font.Bold = False
.HorizontalAlignment = xlRight
End With
' D: текст
With ws.Cells(currentRow, 4)
.Value = textPart
.Font.Bold = False
End With
' E: доп1
With ws.Cells(currentRow, 5)
.Value = extra1
.Font.Bold = False
End With
' F: доп2
With ws.Cells(currentRow, 6)
.Value = extra2
.Font.Bold = False
End With
NextItem:
Next i
' 8. Автоподбор высоты
ws.Rows(SavedRow & ":" & SavedRow + totalLines - 1).EntireRow.AutoFit
' 9. Удаление строк до следующей объединённой ячейки в C/D (как раньше)
Dim lastInsertedRow As Long
lastInsertedRow = SavedRow + totalLines - 1
Dim nextMergedRow As Long
nextMergedRow = 0
Dim r As Long
For r = lastInsertedRow + 1 To lastInsertedRow + 1000
If ws.Cells(r, 3).MergeCells Or ws.Cells(r, 4).MergeCells Then
If ws.Cells(r, 3).MergeCells Then
nextMergedRow = ws.Cells(r, 3).MergeArea.Row
Else
nextMergedRow = ws.Cells(r, 4).MergeArea.Row
End If
Exit For
End If
Next r
If nextMergedRow > 0 Then
Dim firstRowToDelete As Long, lastRowToDelete As Long
firstRowToDelete = lastInsertedRow + 1
lastRowToDelete = nextMergedRow - 1
If lastRowToDelete >= firstRowToDelete Then
ws.Rows(firstRowToDelete & ":" & lastRowToDelete).Delete Shift:=xlUp
End If
End If
Application.ScreenUpdating = True
End Sub
Sub ОтменитьПоследнююВставкуСписка()
If SavedNumLines <= 0 Then
MsgBox "Нет данных для отмены последней вставки.", vbInformation
Exit Sub
End If
Dim ws As Worksheet
Set ws = ActiveSheet
Application.ScreenUpdating = False
ws.Rows(SavedRow & ":" & SavedRow + SavedNumLines - 1).Delete Shift:=xlUp
If Not IsEmpty(SavedOldData) Then
Dim rngRestore As Range
Set rngRestore = ws.Range(ws.Cells(SavedRow, 3), ws.Cells(SavedRow + SavedNumLines - 1, 6))
rngRestore.Value = SavedOldData
End If
SavedNumLines = 0
SavedOldData = Empty
Application.ScreenUpdating = True
End Sub