Блокировка содержимого ячейки в вкладке слова в VBA - PullRequest
0 голосов
/ 26 июня 2018

Меня просят создать макрос VBA, который будет создавать таблицу, каждая таблица, созданная с помощью этого макроса, должна иметь уникальный номер в первой ячейке. Пользователь не должен иметь возможность изменять этот номер.

Есть ли способ заблокировать модификацию ячейки? Я не могу найти его в слове VBA.

Спасибо

Sub Tables()


    Dim cpt As Integer
    cpt = 0


    ThisDocument.Tables.Add Range:=Selection.Range, NumRows:=3, NumColumns:=3, _
                          DefaultTableBehavior:=wdWord9TableBehavior, _
                          AutoFitBehavior:=wdAutoFitFixed

    Dim oTbl As Table

    For Each oTbl In ActiveDocument.Tables
        cpt = cpt + 1
        ActiveDocument.Tables(cpt).Cell(1, 1).Range.Text = "Table n°" & cpt
    Next oTbl

    Selection.GoTo What:=wdGoToPage, Which:=wdGoToNext

End Sub

Ответы [ 2 ]

0 голосов
/ 26 июня 2018

Ответ на ваш вопрос «Да». Можно защитить только определенные части документа, в то же время защищая другие части, хотя от того, что вы хотите сделать, зависит, насколько это может быть сложно.

Возможно, вы захотите прочитать следующую документацию, чтобы закрепить ваше понимание некоторых ключевых ссылок.

  1. Объект выбора (документация MSDN)
  2. Перечисление wdUnits (документация MSDN)
  3. Метод Document.Protect (документация MSDN)
  4. Перечисление wdProtectionType (документация MSDN)
  5. Разрешить изменения частей защищенного документа (показывает шаги пользовательского интерфейса, которые можно использовать для записи макроса)

ПРИМЕЧАНИЕ: Я уверен, что есть более понятный и практичный способ написать это, однако то, что я разработал, работает так, как вы хотите.

Таким образом, с помощью некоторых счетчиков и нескольких операторов if... я смог заставить работать следующий код.

Единственное, что вы можете сделать, это добавить некоторый код в ваш код Sub Table(), чтобы переместить курсор в правильное место и снять защиту документа перед добавлением новой таблицы (как будто вы пытаетесь добавить новую таблицу, пока документ защищен, это даст вам ошибку во время выполнения).

Вот что я придумал (я приведу некоторые объяснения под кодом):

Sub TestPartProtect()

Dim i As Long
Dim c As Long
Dim r As Long
Dim t As Long
Dim myCount As Long
Dim myDoc As Object

i = 1
c = 1
r = 1
t = ActiveDocument.Tables.Count
myCount = 1
Set myDoc = ActiveDocument

myRepeat:
If i > t Then GoTo myProtect
mydoc.Tables(i).Cell(r, c).Select

With Selection
    If myCount = 1 Then
        myCount = myCount + 1
        c = c + 1
        GoTo myRepeat
    ElseIf myCount > 1 Then
        Selection.Editors.Add wdEditorEveryone
        c = c + 1
        myCount = myCount + 1
    End If
        If c > myDoc.Tables(i).Columns.Count Then
            c = 1
            r = r + 1
        End If
            If r > myDoc.Tables(i).Rows.Count Then
            r = 1
            i = i + 1
            myCount = 1
            GoTo myRepeat
            End If

GoTo myRepeat
End With

myProtect:
myDoc.Protect wdAllowOnlyReading

End Sub

Так сверху донизу; переменные i, c, r, t и myCount используются в качестве счетчиков.

i представляет целое число, которое динамически используется для ссылки на индексы таблиц. Это помогает вашему коду работать более чем с 1 конкретной таблицей без необходимости переписывать ваш код сотни раз. Я объясню дальше, после других.

c представляет целое число для номера столбца, на который ссылается код.

r представляет целое число для номера строки, на которую ссылается код.

t представляет общее количество таблиц в ActiveDocument.

myCount представляет количество клеток. Каждый раз, когда на ячейку ссылаются, myCount увеличивается.

Более подробно: для каждой ячейки таблицы, если это ячейка (1, 1), она игнорируется и код перемещается в следующую ячейку. От ячейки (1, 2) до ячейки (3, 3), она помещает исключение защиты для ВСЕХ пользователей в ячейку и увеличивает соответствующие счетчики на ходу. Как только c больше, чем фактическое количество столбцов в таблице, c сбрасывается в 1, а r увеличивается на 1. Когда r больше, чем фактическое количество строк в таблице, оно сбрасывается до 1, i увеличивается на 1 (готов сослаться на следующую таблицу в документе), а myCount сбрасывается на 1 (готов начать заново). Если i больше, чем фактическое количество таблиц в ActiveDocument, тогда код направляется на GoTo Protection, который затем защищает весь документ только для чтения, кроме исключенных разделов, которые мы только что установили.

0 голосов
/ 26 июня 2018

Это немного сложно, потому что есть только один вид защиты, который вы можете использовать для этого: защита только для чтения.По умолчанию, когда это активировано, весь документ заблокирован, и вам необходимо применить разрешение на редактирование в любом месте (диапазонах), которое пользователь может редактировать.То, что вы хотите сделать, в значительной степени противоположно: заблокировать только несколько мест.

Хотя это возможно, заблокировать только ячейку в таблице непросто.Работает только сначала блокируя всю таблицу, затем освобождая ячейки одну за другой, за исключением той, которую нужно заблокировать.

Составляя эту таблицу, необходимо создать таблицу в разблокированной среде, затемБлокировка должна быть активирована на столе.При этом блокируется весь документ.

Таким образом, следующий код

  1. снимает защиту документа, если защита действует.
  2. Позволяет редактировать весь документ
  3. Создает новую таблицу
  4. Немедленно блокирует таблицу (удаляя редактирование для всего документа)
  5. Повторяет все таблицы в документе
  6. Помещает число впервая ячейка
  7. Разблокирует все ячейки, кроме первой
  8. Восстанавливает редактирование для всех абзацев в документе , за исключением тех, что в таблицах
  9. Защищает документ кактолько для чтения

Вот код:

Sub TableProtectFirstCell()
    Dim doc As Word.Document
    Dim ed As Word.Editor
    Dim oTbl As Table, tbl As Table
    Dim celRange As Word.Range, cel As Word.Cell
    Dim cpt As Long
    Dim para As Word.Paragraph

    Set doc = ActiveDocument
    If doc.ProtectionType <> wdNoProtection Then
        doc.Unprotect
    End If
    doc.content.Editors.Add Word.WdEditorType.wdEditorEveryone
    cpt = 0


    Set oTbl = doc.Tables.Add(Range:=Selection.Range, NumRows:=3, NumColumns:=3, _
                          DefaultTableBehavior:=wdWord9TableBehavior, _
                          AutoFitBehavior:=wdAutoFitFixed)
    If oTbl.Range.Editors.Count > 0 Then
        oTbl.Range.Editors(Word.WdEditorType.wdEditorEveryone).Delete
    End If


    For Each tbl In ActiveDocument.Tables
        cpt = cpt + 1
        Set celRange = tbl.Cell(1, 1).Range
        celRange.Text = "Table n°" & cpt
        If celRange.Editors.Count > 0 Then
            celRange.Editors(Word.WdEditorType.wdEditorEveryone).Delete
        Else
            For Each cel In tbl.Range.Cells
                If cel.rowIndex = 1 And cel.ColumnIndex = 1 Then
               Else
                    cel.Range.Editors.Add Word.WdEditorType.wdEditorEveryone
                End If
            Next
        End If
    Next tbl
    For Each para In doc.Paragraphs
        If Not para.Range.Information(wdWithInTable) Then
         para.Range.Editors.Add wdEditorEveryone
        End If
    Next
    doc.Protect wdAllowOnlyReading
End Sub
...