1

Тема: Элементы управления содержимым. Изменение свойств

Добрый день форумчане, выручайте!
Помогите с макросом, вроде все просто но я не умею их писать.
Нужно всего лишь во всем документе в Элементах управления содержимым "поле со спискам" в его свойствах изменить значение показывать как "ограничивающий прямоугольник" на значение "нет", ну и наоборот во всех элементах управления содержимым "поле со спискам" в его свойствах значение показывать как "нет" заменить на значение "ограничивающий прямоугольник"

Post's attachments

2018-10-01_02-41-58.png
2018-10-01_02-41-58.png 37.39 Кб, файл не был скачан. 

You don't have the permssions to download the attachments of this post.

2

Re: Элементы управления содержимым. Изменение свойств

Hishnik пишет:

Добрый день форумчане, выручайте!
Помогите с макросом, вроде все просто но я не умею их писать.
Нужно всего лишь во всем документе в Элементах управления содержимым "поле со спискам" в его свойствах изменить значение показывать как "ограничивающий прямоугольник" на значение "нет", ну и наоборот во всех элементах управления содержимым "поле со спискам" в его свойствах значение показывать как "нет" заменить на значение "ограничивающий прямоугольник"

Попробуйте вот этот макрос

Sub ChangeContentControlsAppearance()
'In a document, for each content control (if it is a combo-box)
'change properties of content controls appearance
'from boundingbox to hidden and vice versa
Dim CC As ContentControl
For Each CC In ActiveDocument.ContentControls
    If CC.Type = wdContentControlComboBox Then
        If CC.Appearance = wdContentControlBoundingBox Then
            CC.Appearance = wdContentControlHidden
        ElseIf CC.Appearance = wdContentControlHidden Then
            CC.Appearance = wdContentControlBoundingBox
        Else 'for other types of CC, e.g., wdContentControlTags
        End If
    End If
Next
End Sub

3

Re: Элементы управления содержимым. Изменение свойств

yshindin пишет:
Hishnik пишет:

Добрый день форумчане, выручайте!
Помогите с макросом, вроде все просто но я не умею их писать.
Нужно всего лишь во всем документе в Элементах управления содержимым "поле со спискам" в его свойствах изменить значение показывать как "ограничивающий прямоугольник" на значение "нет", ну и наоборот во всех элементах управления содержимым "поле со спискам" в его свойствах значение показывать как "нет" заменить на значение "ограничивающий прямоугольник"

Попробуйте вот этот макрос

Sub ChangeContentControlsAppearance()
'In a document, for each content control (if it is a combo-box)
'change properties of content controls appearance
'from boundingbox to hidden and vice versa
Dim CC As ContentControl
For Each CC In ActiveDocument.ContentControls
    If CC.Type = wdContentControlComboBox Then
        If CC.Appearance = wdContentControlBoundingBox Then
            CC.Appearance = wdContentControlHidden
        ElseIf CC.Appearance = wdContentControlHidden Then
            CC.Appearance = wdContentControlBoundingBox
        Else 'for other types of CC, e.g., wdContentControlTags
        End If
    End If
Next
End Sub

Спасибо большое. Все работает, только непосредственно из VisualBasic, а из списка макросов выдает ошибку.

Post's attachments

2018-10-01_22-32-42.png
2018-10-01_22-32-42.png 18.26 Кб, файл не был скачан. 

You don't have the permssions to download the attachments of this post.

4

Re: Элементы управления содержимым. Изменение свойств

Hishnik пишет:

. . .
Спасибо большое. Все работает, только непосредственно из VisualBasic, а из списка макросов выдает ошибку.
. . .

Вам надо разрешить исполнение макросов Word. Привожу пример для английского интерфейса Word:  установите вручную в Word (File -> Options -> Trust Center ->Trust Center Settings-> Macro Settings …) опцию Enable all Macros и отметьте флажок Trust access to VBA project object model. Это разрешение на запуск всех макросов.
Там есть и другие варианты разрешений: можно разрешать запуск макросов только из доверенной папки, разрешать макросы, подписанные сертификатом. По умолчанию (как у вас), не разрешать (или разрешать с подтверждением).

5

Re: Элементы управления содержимым. Изменение свойств

yshindin пишет:
Hishnik пишет:

. . .
Спасибо большое. Все работает, только непосредственно из VisualBasic, а из списка макросов выдает ошибку.
. . .

Вам надо разрешить исполнение макросов Word. Привожу пример для английского интерфейса Word:  установите вручную в Word (File -> Options -> Trust Center ->Trust Center Settings-> Macro Settings …) опцию Enable all Macros и отметьте флажок Trust access to VBA project object model. Это разрешение на запуск всех макросов.
Там есть и другие варианты разрешений: можно разрешать запуск макросов только из доверенной папки, разрешать макросы, подписанные сертификатом. По умолчанию (как у вас), не разрешать (или разрешать с подтверждением).

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

6

Re: Элементы управления содержимым. Изменение свойств

В идеале мне конечно вот такой вот вариант раскрывающего списка:
Раскрывающий список несколькими вариантами выбора, на против них галочки для того что бы можно было выбрать необходимые позиции и после сворачивания списка оставались только отмеченные  smile . Такое возможно ?
Ну и естественно при копирования такого списка и изменении в одном месте менялись и остальные дубликаты  smile .

7

Re: Элементы управления содержимым. Изменение свойств

Hishnik пишет:

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

Чтобы перехватывать событие изменения в элементе управления содержимым (ЭУС, в нашем случае, это поле со списком), нужно, чтобы в документе был реализован перехватчик события изменения. Для этого сам документ должен поддерживать макросы (т.е., быть .docm). Также в нем должна быть реализован VBA-код перехвата в такой процедуре:

Private Sub Document_ContentControlOnExit(ByVal ContentControl As ContentControl, Cancel As Boolean)

End Sub

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

8

Re: Элементы управления содержимым. Изменение свойств

Hishnik пишет:

В идеале мне конечно вот такой вот вариант раскрывающего списка:
Раскрывающий список несколькими вариантами выбора, на против них галочки для того что бы можно было выбрать необходимые позиции и после сворачивания списка оставались только отмеченные  smile . Такое возможно ?
Ну и естественно при копирования такого списка и изменении в одном месте менялись и остальные дубликаты  smile .

Множественный выбор поддерживают, напр., списки типа ListBox (это уже не ЭУС, а управляющие элементы ActiveX, для их поддержки необходимо включить в VBA-проект вашего документа .docm поддержку Microsoft Forms 2.0). В списке типа ListBox галочек нет, но видны выделенные элементы. Выбирать несколько элементов в таком списке нужно, удерживая нажатой клавишу Ctrl.
Для реализации обработки списка сначала создайте его в документе (выбирая элемент

9

Re: Элементы управления содержимым. Изменение свойств

Hishnik пишет:

В идеале мне конечно вот такой вот вариант раскрывающего списка:
Раскрывающий список несколькими вариантами выбора, на против них галочки для того что бы можно было выбрать необходимые позиции и после сворачивания списка оставались только отмеченные  smile . Такое возможно ?
Ну и естественно при копирования такого списка и изменении в одном месте менялись и остальные дубликаты  smile .

ОПЯТЬ ТЕКСТ ОБРЕЗАЛСЯ ((

Множественный выбор поддерживают, напр., списки типа ListBox (это уже не ЭУС, а управляющие элементы ActiveX, для их поддержки необходимо включить в VBA-проект вашего документа .docm поддержку Microsoft Forms 2.0). В списке типа ListBox галочек нет, но видны выделенные элементы. Выбирать несколько элементов в таком списке нужно, удерживая нажатой клавишу Ctrl.
Для реализации обработки списка сначала создайте его в документе (выбирая элемент "Список" из доступных ActiveX-элементов на вкладке Разработчик). Однако наполнять его, программно выделять элементы списка и выяснять, какие элементы списка выбраны, следует программно. Вот примеры.
В примерах:
- FillInLBX = программа начального наполнения списка
- SelectValuesInLBX = программная реализация выбора некоторых элементов  (элементы в списке имеют индексы, начиная с нуля)
- ListSelectedValues = пример получения выделенных в списке элементов (в виде строки)
- GetSelectedItems = функция получения строки со списком выделенных элементов (взято на внешняя ссылка
Надеюсь, вы сможете разработать то, что вам нужно, на базе этих примеров.

Sub FillInLBX()
ListBox1.MultiSelect = fmMultiSelectExtended
ListBox1.AddItem "11"
ListBox1.AddItem "12"
ListBox1.AddItem "13"
ListBox1.AddItem "14"
End Sub

Sub SelectValuesInLBX()
Dim i As Long
Dim lbox As ListBox
Set lbox = ThisDocument.ListBox1
'Unselect all
For i = 0 To lbox.ListCount - 1
    lbox.Selected(i) = False
Next i
'Select some
lbox.Selected(1) = True
lbox.Selected(3) = True
End Sub

Sub ListSelectedValues()
Dim LB_sel As String
Dim lbox As ListBox
Set lbox = ThisDocument.ListBox1
LB_sel = GetSelectedItems(lbox)
End Sub

Function GetSelectedItems(ByRef lbox As ListBox) As String
'returns an array of selected items in a ListBox
Dim tmpArray() As Variant
Dim i As Integer
Dim selCount As Integer
    selCount = -1
    '## Iterate over each item in the ListBox control:
    For i = 0 To lbox.ListCount - 1
        '## Check to see if this item is selected:
        If lbox.Selected(i) = True Then
            '## If this item is selected, then add it to the array
            selCount = selCount + 1
            ReDim Preserve tmpArray(selCount)
            tmpArray(selCount) = lbox.List(i)
        End If
    Next
    If selCount = -1 Then
        '## If no items were selected, return an empty string
        GetSelectedItems = "" ' or "No items selected", etc.
    Else:
        '## Otherwise, return the array of items as a string,
        '   delimited by commas
        GetSelectedItems = Join(tmpArray, ", ")
    End If
End Function

10

Re: Элементы управления содержимым. Изменение свойств

yshindin пишет:

Множественный выбор поддерживают, напр., списки типа ListBox (это уже не ЭУС, а управляющие элементы ActiveX, для их поддержки необходимо включить в VBA-проект вашего документа .docm поддержку Microsoft Forms 2.0). В списке типа ListBox галочек нет, но видны выделенные элементы. Выбирать несколько элементов в таком списке нужно, удерживая нажатой клавишу Ctrl.
Для реализации обработки списка сначала создайте его в документе (выбирая элемент "Список" из доступных ActiveX-элементов на вкладке Разработчик). Однако наполнять его, программно выделять элементы списка и выяснять, какие элементы списка выбраны, следует программно. Вот примеры.
В примерах:
- FillInLBX = программа начального наполнения списка
- SelectValuesInLBX = программная реализация выбора некоторых элементов  (элементы в списке имеют индексы, начиная с нуля)
- ListSelectedValues = пример получения выделенных в списке элементов (в виде строки)
- GetSelectedItems = функция получения строки со списком выделенных элементов (взято на внешняя ссылка
Надеюсь, вы сможете разработать то, что вам нужно, на базе этих примеров.

Sub FillInLBX()
ListBox1.MultiSelect = fmMultiSelectExtended
ListBox1.AddItem "11"
ListBox1.AddItem "12"
ListBox1.AddItem "13"
ListBox1.AddItem "14"
End Sub

Sub SelectValuesInLBX()
Dim i As Long
Dim lbox As ListBox
Set lbox = ThisDocument.ListBox1
'Unselect all
For i = 0 To lbox.ListCount - 1
    lbox.Selected(i) = False
Next i
'Select some
lbox.Selected(1) = True
lbox.Selected(3) = True
End Sub

Sub ListSelectedValues()
Dim LB_sel As String
Dim lbox As ListBox
Set lbox = ThisDocument.ListBox1
LB_sel = GetSelectedItems(lbox)
End Sub

Function GetSelectedItems(ByRef lbox As ListBox) As String
'returns an array of selected items in a ListBox
Dim tmpArray() As Variant
Dim i As Integer
Dim selCount As Integer
    selCount = -1
    '## Iterate over each item in the ListBox control:
    For i = 0 To lbox.ListCount - 1
        '## Check to see if this item is selected:
        If lbox.Selected(i) = True Then
            '## If this item is selected, then add it to the array
            selCount = selCount + 1
            ReDim Preserve tmpArray(selCount)
            tmpArray(selCount) = lbox.List(i)
        End If
    Next
    If selCount = -1 Then
        '## If no items were selected, return an empty string
        GetSelectedItems = "" ' or "No items selected", etc.
    Else:
        '## Otherwise, return the array of items as a string,
        '   delimited by commas
        GetSelectedItems = Join(tmpArray, ", ")
    End If
End Function

Со ссылкой получилось Спасибо! в крайнем случае так наверное придется делать.

А вот со списком типа ListBox что то не совсем. Вроде создал список. Да выделяются через Ctrl строчки, но мне надо что бы после выбора лишнее (не выбранное) скрывалось и не печаталось. Ну и потом при необходимости можно было изменить выбор и опять же другие не выделенные элементы скрывались.

Извините, что может я чего то не допонял.

Post's attachments

Шаблон.docm 96.94 Кб, файл не был скачан. 

You don't have the permssions to download the attachments of this post.

11

Re: Элементы управления содержимым. Изменение свойств

Hishnik пишет:

. . .
А вот со списком типа ListBox что то не совсем. Вроде создал список. Да выделяются через Ctrl строчки, но мне надо что бы после выбора лишнее (не выбранное) скрывалось и не печаталось. Ну и потом при необходимости можно было изменить выбор и опять же другие не выделенные элементы скрывались.
. . .

Это только на первый взгляд кажется, что тут пара пустяков. На самом деле вот какие сложности:
- Элемент управления ListBox не содержит внутреннего атрибута (типа "Tag"), в котором можно было бы хранить все значения, которые могли бы выбираться. Поэтому придется пользоваться внешними, напр., в Word есть такой аппарат, как пользовательские свойства (Properties). Можно придумать структуру строки с разделителями, отражающую значения всех переменных и признак их последнего выбора. Напр., пусть это свойство имеет наименование "LB1". Пример значения этого свойства:
   |/Элем1/0/|/Элем2/1/|/Элем3/0/|/Элем4/1/|/Элем5/1/|
Здесь элементы списка представлены с разделителем - вертикальной чертой, а каждый элемент имеет два значения: значение элемента списка и значение того, выбран ли он. Программно можно легко добраться до любого параметра внутри такой строки.
- Для элемента ListBox нужно запрограммировать события GotGocus и LostFocus (поддерживаемые для объектов типа ListBox).
Первое из них должно срабатывать, когда пользователь кликнет в элементе ListBox. Тогда перехватчик этого события (GotFocus) должен извлечь из строки свойства LB1 (см.выше) все значения элементов списка и пересоздать список, выделив в нем элементы, выбранные в последний раз.
Второе событие (LostFocus) должно срабатывать после того, как пользователь кликнет в документе в любом месте вне списка. Тогда перехватчик LostFocus должен понять, что пользователь выбрал в последний раз, заново сформировать свойство LB1 и, наконец, переформировать список ListBox, оставив в нем только выбранные пользователем значения. При этом макрос из LostFocus должен еще и сохранить весь документ.
Возможно, получится обойтись только перехватчиком LostFocus.
Рассказывать все это - долго, реализовать и проверять - еще дольше.  Так что попробуйте придумать что-нибудь попроще )).
Дискуссию на эту тему закрываю.

12

Re: Элементы управления содержимым. Изменение свойств

yshindin пишет:

Это только на первый взгляд кажется, что тут пара пустяков. На самом деле вот какие сложности:
- Элемент управления ListBox не содержит внутреннего атрибута (типа "Tag"), в котором можно было бы хранить все значения, которые могли бы выбираться. Поэтому придется пользоваться внешними, напр., в Word есть такой аппарат, как пользовательские свойства (Properties). Можно придумать структуру строки с разделителями, отражающую значения всех переменных и признак их последнего выбора. Напр., пусть это свойство имеет наименование "LB1". Пример значения этого свойства:
   |/Элем1/0/|/Элем2/1/|/Элем3/0/|/Элем4/1/|/Элем5/1/|
Здесь элементы списка представлены с разделителем - вертикальной чертой, а каждый элемент имеет два значения: значение элемента списка и значение того, выбран ли он. Программно можно легко добраться до любого параметра внутри такой строки.
- Для элемента ListBox нужно запрограммировать события GotGocus и LostFocus (поддерживаемые для объектов типа ListBox).
Первое из них должно срабатывать, когда пользователь кликнет в элементе ListBox. Тогда перехватчик этого события (GotFocus) должен извлечь из строки свойства LB1 (см.выше) все значения элементов списка и пересоздать список, выделив в нем элементы, выбранные в последний раз.
Второе событие (LostFocus) должно срабатывать после того, как пользователь кликнет в документе в любом месте вне списка. Тогда перехватчик LostFocus должен понять, что пользователь выбрал в последний раз, заново сформировать свойство LB1 и, наконец, переформировать список ListBox, оставив в нем только выбранные пользователем значения. При этом макрос из LostFocus должен еще и сохранить весь документ.
Возможно, получится обойтись только перехватчиком LostFocus.
Рассказывать все это - долго, реализовать и проверять - еще дольше.  Так что попробуйте придумать что-нибудь попроще )).
Дискуссию на эту тему закрываю.

Хорошо. Спасибо большое!