3 / 3 / 0
Регистрация: 27.02.2014
Сообщений: 36
1

VBA в Word. Обработать ячейки таблицы, в которых содержатся цифры

09.03.2014, 19:01. Показов 23725. Ответов 16
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Уже третий день не могу вникнуть в VBA в Word при работе с таблицами. Контрольная подвисла, время начинает поджимать, но нужно разобраться, а не банально копипастом все делать.

Задание вкратце:
В документе ворда есть таблица в ячейках которой содержится что угодно. Нужно макросом прошустрить выделенные клетки (по-умолчанию область прямоугольная), обработать только ячейки в которых содержатся цифры. Для каждого столбца необходимо вычислить среднее значение. Все средние значения вывести в строке, вставленной ниже выделенной области в соответствующих столбцах.

Что сделано на данный момент:

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Sub NewRowWithResults()
Dim xxx As Column
Dim yyy As Cell
Dim sum As Integer
Dim cnt As Integer
 
 
For Each xxx In Selection.Range.Columns
    sum = 0
    cnt = 0
    For Each yyy In xxx.Cells
        If IsNumeric(yyy.Range.Text) Then
            sum = sum + yyy.Range.Text
            cnt = cnt + 1
        End If
    Next yyy
    ActiveDocument.Tables(1).Cell(1, 9).Range = sum
    ActiveDocument.Tables(1).Cell(1, 10).Range = cnt
Next xxx
 
'ActiveDocument.Tables(1).Cell(1, 9).Range = sum
'ActiveDocument.Tables(1).Cell(1, 10).Range = cnt
'Selection.InsertRowsBelow 1
End Sub
В данном примере выделаю 1 столбец и запускаю макрос. Проблема в том, что sum = 0 и cnt = 0 тоже.
Судя по продолжительности моргания выделенной области, могу предположить, что макрос перебирает все ячейки таблицы, а не только выделенного региона.

Прошу вашей помощи.
0
Лучшие ответы (1)
09.03.2014, 19:01
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
09.03.2014, 19:01
Ответы с готовыми решениями:

Как с помощью VBA получить значение с ячейки таблицы MS Word в переменую?
Как с помощью VBA получить значение с ячейки таблицы MS Word в переменую. Range(x,y).???

Vba. Таблицы в ms word
Известна дата рождения Пети. Определить дату рождения Коли, если известно, что число дней, прожитых им до текущего дня, в 2 раза меньше,...

Вывести на экран строки в которых содержатся цифры
Прошу помощи в написании программы. Задание: Сформировать и вывести на экран текстовый файл в котором исключить слова "while",...

16
15155 / 6428 / 1731
Регистрация: 24.09.2011
Сообщений: 9,999
09.03.2014, 19:26 2
Цитата Сообщение от Silvermatic Посмотреть сообщение
Проблема в том, что sum = 0 и cnt = 0 тоже
Текст ячейки всегда содержит в конце 2 символа chr(13)+chr(7), поэтому IsNumeric(yyy.Range.Text) всегда False.
Поскольку "нужно разобраться" , решение приводить не буду.

Цитата Сообщение от Silvermatic Посмотреть сообщение
могу предположить, что макрос перебирает все ячейки таблицы
Чтобы не гадать, поставьте в цикл yyy.select и пройдите по шагам - F8.
0
 Аватар для Sasha_Smirnov
5562 / 1368 / 150
Регистрация: 08.02.2009
Сообщений: 4,109
Записей в блоге: 30
09.03.2014, 20:58 3
Лучший ответ Сообщение было отмечено как решение

Решение

Поэкспериментировав в окне Immediate, пока сделал такой вот набросок:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
'Здесь надо выделить область в таблице Word
 
Sub AverageOfSelectedColumn()
Dim x1, x2, y1, y2
''вставка таблицы X на Y
'ActiveDocument.Tables.Add Selection.Range, 5, 5
 
    'координаты выделения
    x1 = Selection.Columns.First.Index
    x2 = Selection.Columns.Last.Index
    y1 = Selection.Rows.First.Index
    y2 = Selection.Rows.Last.Index
    
    Selection.Rows.Last.Range.Rows.Add 'добавление строки под выделением
    
    ActiveDocument.Tables(1).Cell(y2 + 1, x1).Formula "=Average(above)"
End Sub
Миниатюры
VBA в Word. Обработать ячейки таблицы, в которых содержатся цифры  
1
3 / 3 / 0
Регистрация: 27.02.2014
Сообщений: 36
09.03.2014, 21:06  [ТС] 4
Цитата Сообщение от Казанский Посмотреть сообщение
Текст ячейки всегда содержит в конце 2 символа chr(13)+chr(7), поэтому IsNumeric(yyy.Range.Text) всегда False.
Поскольку "нужно разобраться" , решение приводить не буду.
yyy.Range.Text преобразовать и перенести в массив чаров, определить длину и затереть 2 последних символа?
Цитата Сообщение от Казанский Посмотреть сообщение
Чтобы не гадать, поставьте в цикл yyy.select и пройдите по шагам - F8.
Как и подозревал, проходит по всей таблице...
Тут трабла даже в другом. Изначально пробовал определить границы выделенной области таким способом:

Visual Basic
1
2
3
4
5
6
7
8
9
10
dim cb as integer ' column - begin
dim ce as integer ' column - end
dim rb as integer ' row - begin
dim re as integer ' row - end
 
cb = Selection.Range.FirstColumn
ce = Selection.Range.Columns.Count
 
rb = Selection.Range.FirstRow
re = Selection.Range.Rows.Count
Со строками все определялось нормально, а со столбцами не проходило - значения были от 1(cb) до 10(ce), т.е. прорабатывали все столбцы таблицы, а не те что были выделены.
0
 Аватар для Sasha_Smirnov
5562 / 1368 / 150
Регистрация: 08.02.2009
Сообщений: 4,109
Записей в блоге: 30
09.03.2014, 21:12 5
Вот наиболее близкий к заданию код. По крайней мере — по координатам выделения.
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Sub AveragesOfSelectedColumns()
Dim x1, x2, y1, y2, j
    'координаты выделения
    x1 = Selection.Columns.First.Index
    x2 = Selection.Columns.Last.Index
    y1 = Selection.Rows.First.Index
    y2 = Selection.Rows.Last.Index
    
    Selection.Rows.Last.Range.Rows.Add 'добавление строки под выделением
    
    For j = x1 To x2
        ActiveDocument.Tables(1).Cell(y2 + 1, j).Formula _
        "=sum(above)" & "/" & y2 - y1 + 1
    Next
End Sub
Поле {=sum(above)}*, конечно, суммирует всё, что сверху — ну это так, просто демо.
___________________
* в таблице его код (после прогона данного примера) можно посмотреть по Alt-F9
2
3 / 3 / 0
Регистрация: 27.02.2014
Сообщений: 36
09.03.2014, 21:19  [ТС] 6
Цитата Сообщение от Sasha_Smirnov Посмотреть сообщение
Вот наиболее близкий к заданию код. По крайней мере — по координатам выделения.
Я уже опробовал ваш код.
Границы выделенной области определяются устойчиво.

Вопрос по вставке строки под выделенной областью. Такой вариант чем-нибудь плох?
Visual Basic
1
Selection.InsertRowsBelow 1
Он нормально работает, но вдруг есть тонкости...
0
15155 / 6428 / 1731
Регистрация: 24.09.2011
Сообщений: 9,999
09.03.2014, 21:37 7
Мой вариант
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Sub bb()
Dim c As Cell, col1&, col2&
With Selection
  If Not .Information(wdWithInTable) Then
    MsgBox "Выделение не в таблице!", vbCritical
    Exit Sub
  End If
  col1 = .Cells(1).ColumnIndex
  col2 = .Cells(.Cells.Count).ColumnIndex
  ReDim sum(col1 To col2)
  For Each c In .Cells
    sum(c.ColumnIndex) = sum(c.ColumnIndex) + Val(c.Range.Text)
  Next
  With .Rows.Last.Range.Rows.Add 'Sasha_Smirnov
    For col1 = col1 To col2
      .Cells(col1).Range = sum(col1)
    Next
  End With
End With
End Sub
Добавлено через 8 минут
Чтобы работало с любым десятичным разделителем, строка 12
Visual Basic
1
    sum(c.ColumnIndex) = sum(c.ColumnIndex) + Val(Replace(c.Range.Text, ",", "."))
2
3 / 3 / 0
Регистрация: 27.02.2014
Сообщений: 36
09.03.2014, 21:43  [ТС] 8
Казанский, твой вариант "прожует" ячейки в которых содержится текст или пустые ячейки?

По большому счету осталось определить что в ячейке находится именно число, а не что-либо другое.
0
15155 / 6428 / 1731
Регистрация: 24.09.2011
Сообщений: 9,999
09.03.2014, 21:49 9
Silvermatic, попробуй!
И поставь курсор в слово Val, нажми F1.
1
3 / 3 / 0
Регистрация: 27.02.2014
Сообщений: 36
09.03.2014, 23:53  [ТС] 10
Казанский, хоть и не совсем то, что нужно, но в таком виде будет достаточно съедобно, ибо лекций VBA не прочитали и 40%.
Благодарствую.
0
 Аватар для Sasha_Smirnov
5562 / 1368 / 150
Регистрация: 08.02.2009
Сообщений: 4,109
Записей в блоге: 30
10.03.2014, 00:11 11
Добил-таки свой эксселеподобный (с формулами) вариант. Разделитель дробей запятая.

Действует лишь на 1-ю таблицу в документе.
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Option Explicit
 
'здесь надо выделить область в таблице Word
 
Sub AveragesOfColumnsOfSelection()
Dim x1, x2, y1, y2, j
'выход при отсутствии Таблицы 1 и при выделении вне её
If ActiveDocument.Tables.Count = 0 Then Exit Sub
If Not Selection.InRange(ActiveDocument.Tables(1).Range) Then Exit Sub
 
    'координаты выделения
    x1 = Selection.Columns.First.Index
    x2 = Selection.Columns.Last.Index
    y1 = Selection.Rows.First.Index
    y2 = Selection.Rows.Last.Index
    
    Selection.Rows.Last.Range.Rows.Add 'добавление строки под выделением
    
    'перевод номера колонки (1, 2, 3, 4, …) в вид: a, b, c, d, … [не пригодился!]
    
    For j = 64 + x1 To 64 + x2                              'код буквы A = 64 + 1
        ActiveDocument.Tables(1).Cell(y2 + 1, j - 64).Formula _
        "=sum([" & Chr(j) & y1 & ":" & Chr(j) & y2 & "])" & "/" & y2 - y1 + 1
    Next
'в документе, если видны не вычисленные значения, а коды, надо нажать Alt-F9
End Sub
Миниатюры
VBA в Word. Обработать ячейки таблицы, в которых содержатся цифры  
0
15155 / 6428 / 1731
Регистрация: 24.09.2011
Сообщений: 9,999
10.03.2014, 00:13 12
А, там же среднее надо было. Тогда так
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Sub bb()
Dim c As Cell, col1&, col2&, ci&, ct$
With Selection
  If Not .Information(wdWithInTable) Then
    MsgBox "Выделение не в таблице!", vbCritical
    Exit Sub
  End If
  col1 = .Cells(1).ColumnIndex
  col2 = .Cells(.Cells.Count).ColumnIndex
  ReDim sum(col1 To col2), cnt(col1 To col2)
  For Each c In .Cells
    ct = c.Range.Text
    ct = Left$(ct, Len(ct) - 2)
    If IsNumeric(ct) Then
      ci = c.ColumnIndex
      sum(ci) = sum(ci) + CDbl(ct)
      cnt(ci) = cnt(ci) + 1
    End If
  Next
  With .Rows.Last.Range.Rows.Add 'Sasha_Smirnov
    For col1 = col1 To col2
      If cnt(col1) > 0 Then .Cells(col1).Range = sum(col1) / cnt(col1)
    Next
  End With
End With
End Sub
1
3 / 3 / 0
Регистрация: 27.02.2014
Сообщений: 36
10.03.2014, 11:04  [ТС] 13
Спасибо за помощь, ребята. В коде разобрался, сделал на свой манер, все работает.

п.с. Сдать и забыть как страшный сон...
0
 Аватар для Sasha_Smirnov
5562 / 1368 / 150
Регистрация: 08.02.2009
Сообщений: 4,109
Записей в блоге: 30
10.03.2014, 15:16 14
Можно ж было и удовольствие получить от постижения…

А любопытно было бы взглянуть, каков он ваш манер!
0
3 / 3 / 0
Регистрация: 27.02.2014
Сообщений: 36
10.03.2014, 16:16  [ТС] 15
Цитата Сообщение от Sasha_Smirnov Посмотреть сообщение
Можно ж было и удовольствие получить от постижения…
Взглянув на количество объектов, их методов, свойств и параметров, на их замудреную иерархию...
Надо было в начале спросить что и какими функциями сделать, а логику заложить самостоятельно.

Цитата Сообщение от Sasha_Smirnov Посмотреть сообщение
А любопытно было бы взглянуть, каков он ваш манер!
Почему же и не показать? Смотрите...
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Sub NewRowWithResults()
Dim rb As Integer
Dim re As Integer
Dim cb As Integer
Dim ce As Integer
Dim cl As Cell, ct$
 
If Not Selection.Information(wdWithInTable) Then
    MsgBox "Выделение за пределами таблицы!", vbCritical
    Exit Sub
End If
 
rb = Selection.Rows.First.Index
re = Selection.Rows.Last.Index
cb = Selection.Columns.First.Index
ce = Selection.Columns.Last.Index
 
Selection.InsertRowsBelow 1
 
For i = cb To ce
    sum = 0
    cnt = 0
    For j = rb To re
        ct = ActiveDocument.Tables(1).Cell(j, i).Range.Text
        ct = Left$(ct, Len(ct) - 2)
        If IsNumeric(ct) Then
          sum = sum + CDbl(ct)
          cnt = cnt + 1
        End If
    Next j
    If sum <> 0 Then
        ActiveDocument.Tables(1).Cell(re + 1, i).Range = sum / cnt
    End If
Next i
End Sub
Ах, да, вот еще хотел уточнить что объявляется в этой строке? В смысле ни что объявляется, а что за объявление "ct$"?
Visual Basic
1
Dim cl As Cell, ct$
И как вычеркнуть из этого объявления переменную cl. ct$, как я понял, что-то вроде указателя в Си?
1
15155 / 6428 / 1731
Регистрация: 24.09.2011
Сообщений: 9,999
10.03.2014, 18:28 16
Dim ct$ это сокращенная запись Dim ct As String.
Несколько наиболее популярных типов в VB/VBA имеют символы для обозначения типа.
См. F1 - String Data Type, Integer Data Type и т.д.
0
3 / 3 / 0
Регистрация: 27.02.2014
Сообщений: 36
10.03.2014, 19:38  [ТС] 17
Цитата Сообщение от Казанский Посмотреть сообщение
Dim ct$ это сокращенная запись Dim ct As String.
Значит примерно правильно понял. Спасибо за объяснения.
0
10.03.2014, 19:38
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
10.03.2014, 19:38
Помогаю со студенческими работами здесь

Найти сумму цифр тех слов, в которых содержатся только цифры
Здравствуйте. Помогите решить задачу. Найти сумму цифр тех слов, в которых содержатся только цифры.

Найти в строке слова-сообщения, в которых содержатся цифры и вывести их на экран
Вводится строка s, слова разделяются пробелами и разделительными знаками. Надо найти слова-сообщения в которых содержатся цыфры и вывести...

Найти сумму цифр тех слов, в которых содержатся только цифры
Здравствуйте. Помогите решить задачу. Найти сумму цифр тех слов, в которых содержатся только цифры.

word-wrap: break-word и ячейки таблицы
Вот код: &lt;table style=&quot;width: 300px;&quot;&gt; &lt;tr&gt;&lt;td&gt;LALALA&amp;nbsp;&lt;/td&gt;&lt;td style=&quot;word-wrap: break-word; background:...

Обработать скрипт на клик таблицы, кроме последней ячейки
Добрый день, есть такой скрипт: $('#zoneTable tbody tr td').on('click',function(){ $(&quot;#addRecord&quot;).modal(&quot;show&quot;); ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему

Редактор формул (кликните на картинку в правом углу, чтобы закрыть)
Опции темы

Новые блоги и статьи
Микросервис с нуля на Go с Kafka
stackoverflow 12.02.2025
Когда я впервые столкнулся с необходимостью разделить монолитное приложение на микросервисы, передо мной встал вопрос выбора правильных технологий и подходов. После долгих экспериментов с различными. . .
Микросервис с нуля на C# с RabbitMQ
stackoverflow 12.02.2025
Переход от монолитной архитектуры к микросервисной - это не просто модное веяние, а закономерный этап эволюции программных систем. В отличие от монолита, где все компоненты тесно связаны между собой. . .
Docker для начинающих
stackoverflow 12.02.2025
В современном мире разработки программного обеспечения все чаще возникает необходимость быстро и надежно разворачивать приложения в различных средах. Разработчики постоянно сталкиваются с проблемой. . .
Создание бота для Телеграм на C#
stackoverflow 12.02.2025
В современном мире корпоративных коммуникаций Telegram-боты становятся незаменимым средством автоматизации бизнес-процессов и взаимодействия с сотрудниками. Как создать такого бота, который сможет. . .
Операторы сравнения (== и ===) в JavaScript
hw_wired 12.02.2025
JavaScript предоставляет два основных оператора сравнения - оператор нестрогого равенства (==) и оператор строгого равенства (===). На первый взгляд они могут показаться очень похожими, но их. . .
Определение адреса, откуда репозиторий Git был клонирован
hw_wired 12.02.2025
Система контроля версий Git хранит всю информацию о репозитории в специальной директории . git, включая данные об удаленных источниках. Эта информация необходима для синхронизации изменений между. . .
Объединение нескольких коммитов Git в один
hw_wired 12.02.2025
Представьте, что вы работаете над новой функциональностью и создали десяток небольших коммитов: исправление опечатки, форматирование кода, добавление комментариев, реализация основной логики. Каждый. . .
Как добавить локальную ветку в удалённый репозиторий Git
hw_wired 12.02.2025
Локальная ветка в Git - это изолированная линия разработки, существующая только на вашем компьютере. Представьте себе дерево с множеством веток - каждая ветка может расти в своем направлении, не. . .
Статическое отражение в C++
stackoverflow 12.02.2025
Статическое отражение представляет собой мощный механизм, позволяющий программам анализировать и манипулировать своей собственной структурой во время компиляции. Эта возможность открывает. . .
C++ в 21 веке - Бьярне Страуструп
stackoverflow 12.02.2025
В современном мире разработки программного обеспечения C++ продолжает оставаться одним из ключевых языков программирования, несмотря на свой солидный возраст - более 45 лет с момента создания. За это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru