Есть код написанный кем то. Т.к. я не особо разбираюсь в макросах, то пытался переделать его под свои нужды, но по всей видимости, что то не учел.
[vba]
Код
Sub Worksheet_Change(ByVal Target As Range) If Target = Range("B8") Or Target = Range("B9") Or Target = Range("B10") Or Target = Range("B11") Or Target = Range("B12") Or Target = Range("B13") Or Target = Range("B14") Or Target = Range("B15") Or Target = Range("B16") Or Target = Range("B17") Then Call ' [color=green]мой макрос[/color] End If End Sub
[/vba]
Вопрос 1: можно ли упростить строку и какой принцип прописание значений в Range("B11") [vba]
Код
If Target = Range("B8") Or Target = Range("B9") Or Target = Range("B10") Or Target = Range("B11") Or Target = Range("B12") Or Target = Range("B13") Or Target = Range("B14") Or Target = Range("B15") Or Target = Range("B16") Or Target = Range("B17") Then
[/vba]
Вопрос 2: При удалении значений из данных ячеек появляется ошибка run-time error '13' Type mismatch
Как от нее избавиться?
Добрый день,
Есть код написанный кем то. Т.к. я не особо разбираюсь в макросах, то пытался переделать его под свои нужды, но по всей видимости, что то не учел.
[vba]
Код
Sub Worksheet_Change(ByVal Target As Range) If Target = Range("B8") Or Target = Range("B9") Or Target = Range("B10") Or Target = Range("B11") Or Target = Range("B12") Or Target = Range("B13") Or Target = Range("B14") Or Target = Range("B15") Or Target = Range("B16") Or Target = Range("B17") Then Call ' [color=green]мой макрос[/color] End If End Sub
[/vba]
Вопрос 1: можно ли упростить строку и какой принцип прописание значений в Range("B11") [vba]
Код
If Target = Range("B8") Or Target = Range("B9") Or Target = Range("B10") Or Target = Range("B11") Or Target = Range("B12") Or Target = Range("B13") Or Target = Range("B14") Or Target = Range("B15") Or Target = Range("B16") Or Target = Range("B17") Then
[/vba]
Вопрос 2: При удалении значений из данных ячеек появляется ошибка run-time error '13' Type mismatch
If Not Intersect(Range("B8:B17"), Target) Is Nothing Then
[/vba] Без файла трудно понять ошибку. Возможно вы удаляете не по одной ячейке. Тогда сделайте проверку на то сколько ячеек изменилось. Или нужен цикл, чтобы при удалении обрабатывалась каждая ячейка отдельно.
PS. Прочтите правила форума.
[vba]
Код
If Not Intersect(Range("B8:B17"), Target) Is Nothing Then
[/vba] Без файла трудно понять ошибку. Возможно вы удаляете не по одной ячейке. Тогда сделайте проверку на то сколько ячеек изменилось. Или нужен цикл, чтобы при удалении обрабатывалась каждая ячейка отдельно.
Все заработало. И ошибка не выскакивает. С правилами форума. просто засада. То на одно не обращу внимание, то на другое. Надеюсь скоро все уложится и косячить перестану. Файл выложить не могу, политика организации не позволяет. Попробую сделать свой пример, аналогичный проекту, а то впоросов чем дальше, тем больше.
AlexM, спасибо огромное
Все заработало. И ошибка не выскакивает. С правилами форума. просто засада. То на одно не обращу внимание, то на другое. Надеюсь скоро все уложится и косячить перестану. Файл выложить не могу, политика организации не позволяет. Попробую сделать свой пример, аналогичный проекту, а то впоросов чем дальше, тем больше.qshin1980
Оригинальный файл никому и не нужен - нужен файл-пример с аналогичным расположением и форматом данных, минимальный по содержанию. Т.е. меняете все гранаты на апельсины, удаляете лишние строки, вообще всё не относящееся к делу, лучше переносите лист в новую книгу, её и показываете. Если есть свой макрос в модуле - добавляете в книгу его (лучше без лишних макросов, не имеющих значения в вопросе). Тогда и секретность не нарушите, и правила соблюдёте, и помощь быстрее получите, без лишних вопросов.
Оригинальный файл никому и не нужен - нужен файл-пример с аналогичным расположением и форматом данных, минимальный по содержанию. Т.е. меняете все гранаты на апельсины, удаляете лишние строки, вообще всё не относящееся к делу, лучше переносите лист в новую книгу, её и показываете. Если есть свой макрос в модуле - добавляете в книгу его (лучше без лишних макросов, не имеющих значения в вопросе). Тогда и секретность не нарушите, и правила соблюдёте, и помощь быстрее получите, без лишних вопросов.Hugo
Заработать то, заработало, но не на всем массиве. Исправляюсь и прикладываю файл, анналогичный тому который перестраиваю. Существует ряд таблиц. Между ними могут быть другие таблицы в которых работа макроса не требуется. Так вот если прописать
[vba]
Код
If Not Intersect(Range("B8:B17"), Target) Is Nothing Then
[/vba]
то вписать больше двух диапазонов не получается. Вписываю третий выдает ошибку. И еще, так как данных на странице много визуально видно как срабатывает макрос. Он сначала разварачивает строки, потом сварачивает. Не очень красиво. Если это можно как то исправить, было бы отлично
Зарание, спасибо
AlexM, добрый день
Заработать то, заработало, но не на всем массиве. Исправляюсь и прикладываю файл, анналогичный тому который перестраиваю. Существует ряд таблиц. Между ними могут быть другие таблицы в которых работа макроса не требуется. Так вот если прописать
[vba]
Код
If Not Intersect(Range("B8:B17"), Target) Is Nothing Then
[/vba]
то вписать больше двух диапазонов не получается. Вписываю третий выдает ошибку. И еще, так как данных на странице много визуально видно как срабатывает макрос. Он сначала разварачивает строки, потом сварачивает. Не очень красиво. Если это можно как то исправить, было бы отлично
Проект растет обретает свой облик. Столкнулся с тем, что макрос приобретает все большие размеры. На листах, с которых запускается макрос, прописываю код, любезно исправленный AlexM. Например:
[vba]
Код
Private Sub Worksheet_Change(ByVal Target As Range) If Not Intersect(Range("B38:B53, BN2, B1"), Target) Is Nothing Then Call УдалениеСтрок End If End Sub
[/vba]
В модуле прописан код:
[vba]
Код
Sub УдалениеСтрок() On Error Resume Next
Dim ra As Range, delra As Range, ТекстДляПоиска As String ТекстДляПоиска = "строку не заполнять" Application.ScreenUpdating = False Sheets("1").Rows.Hidden = False Sheets("2").Rows.Hidden = False Sheets("3").Rows.Hidden = False ' и так еще 20 листов, а далее к каждому из них
Set ra = Nothing Set delra = Nothing
For Each ra In Sheets("1").UsedRange.Rows If Not ra.Find(ТекстДляПоиска, , xlValues, xlPart) Is Nothing Then If delra Is Nothing Then Set delra = ra Else Set delra = Union(delra, ra) End If Next If Not delra Is Nothing Then delra.EntireRow.Hidden = True
Set ra = Nothing Set delra = Nothing
For Each ra In Sheets("2").UsedRange.Rows If Not ra.Find(ТекстДляПоиска, , xlValues, xlPart) Is Nothing Then If delra Is Nothing Then Set delra = ra Else Set delra = Union(delra, ra) End If Next If Not delra Is Nothing Then delra.EntireRow.Hidden = True
Set ra = Nothing Set delra = Nothing
For Each ra In Sheets("3").UsedRange.Rows If Not ra.Find(ТекстДляПоиска, , xlValues, xlPart) Is Nothing Then If delra Is Nothing Then Set delra = ra Else Set delra = Union(delra, ra) End If Next If Not delra Is Nothing Then delra.EntireRow.Hidden = True
'и так еще описаны все 20 листов
[/vba]
Вопрос. Можно ли написать код в модуле более универсально? Да еще так, чтобы добавляя новый лист, не нужно было прописывать его в модуле.
В продолжение.
Проект растет обретает свой облик. Столкнулся с тем, что макрос приобретает все большие размеры. На листах, с которых запускается макрос, прописываю код, любезно исправленный AlexM. Например:
[vba]
Код
Private Sub Worksheet_Change(ByVal Target As Range) If Not Intersect(Range("B38:B53, BN2, B1"), Target) Is Nothing Then Call УдалениеСтрок End If End Sub
[/vba]
В модуле прописан код:
[vba]
Код
Sub УдалениеСтрок() On Error Resume Next
Dim ra As Range, delra As Range, ТекстДляПоиска As String ТекстДляПоиска = "строку не заполнять" Application.ScreenUpdating = False Sheets("1").Rows.Hidden = False Sheets("2").Rows.Hidden = False Sheets("3").Rows.Hidden = False ' и так еще 20 листов, а далее к каждому из них
Set ra = Nothing Set delra = Nothing
For Each ra In Sheets("1").UsedRange.Rows If Not ra.Find(ТекстДляПоиска, , xlValues, xlPart) Is Nothing Then If delra Is Nothing Then Set delra = ra Else Set delra = Union(delra, ra) End If Next If Not delra Is Nothing Then delra.EntireRow.Hidden = True
Set ra = Nothing Set delra = Nothing
For Each ra In Sheets("2").UsedRange.Rows If Not ra.Find(ТекстДляПоиска, , xlValues, xlPart) Is Nothing Then If delra Is Nothing Then Set delra = ra Else Set delra = Union(delra, ra) End If Next If Not delra Is Nothing Then delra.EntireRow.Hidden = True
Set ra = Nothing Set delra = Nothing
For Each ra In Sheets("3").UsedRange.Rows If Not ra.Find(ТекстДляПоиска, , xlValues, xlPart) Is Nothing Then If delra Is Nothing Then Set delra = ra Else Set delra = Union(delra, ra) End If Next If Not delra Is Nothing Then delra.EntireRow.Hidden = True
'и так еще описаны все 20 листов
[/vba]
Вопрос. Можно ли написать код в модуле более универсально? Да еще так, чтобы добавляя новый лист, не нужно было прописывать его в модуле.qshin1980
SkyPro, Я бы поступил иначе! Во первых в вашем способ не учтено что листы могут добавляться и в каждом добавляемом нужно прописывать Worksheet_Change, Во вторых я предполагаю что процедура должна выполняться не одновременно для всех листов а только для активного. Если я прав то я бы поступил иначе. 1) Прописываем модуль класов в котором будем отлавливать событие Worksheet_Change для ВСЕХ листов книги что избавляет нас от необходимости на КАЖДОМ листе прописывать ОДИНАКОВЫЕ Worksheet_Change 2) если я прав и макрос должен работать только для активного листа то заменяю в модуле все ссылки на конкретный лист ссылками на ActiveSheet что избавит от необходимости дописывать одинаковый обработчик для всех листов. Но пока это мои догадки и ТС их не подтвердит конкретного макроса писать нехочу
SkyPro, Я бы поступил иначе! Во первых в вашем способ не учтено что листы могут добавляться и в каждом добавляемом нужно прописывать Worksheet_Change, Во вторых я предполагаю что процедура должна выполняться не одновременно для всех листов а только для активного. Если я прав то я бы поступил иначе. 1) Прописываем модуль класов в котором будем отлавливать событие Worksheet_Change для ВСЕХ листов книги что избавляет нас от необходимости на КАЖДОМ листе прописывать ОДИНАКОВЫЕ Worksheet_Change 2) если я прав и макрос должен работать только для активного листа то заменяю в модуле все ссылки на конкретный лист ссылками на ActiveSheet что избавит от необходимости дописывать одинаковый обработчик для всех листов. Но пока это мои догадки и ТС их не подтвердит конкретного макроса писать нехочуPoltava
Сообщение отредактировал Poltava - Четверг, 03.10.2013, 22:08
А не проще будет положить все это в модуль книги, а не в модуль листа? [vba]
Код
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range) 'тут код макроса, в котором: '''Sh - лист, где происходят изменения '''Target - диапазон на этом листе End Sub
[/vba]
А не проще будет положить все это в модуль книги, а не в модуль листа? [vba]
Код
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range) 'тут код макроса, в котором: '''Sh - лист, где происходят изменения '''Target - диапазон на этом листе End Sub
_Boroda_, В модуль книги еще проще ненужно с класами заморачиваться! А то я как то забыл о том что есть Workbook_SheetChange. просто писал только что код чтобы в нескольких книгах события отлавливать вот меня на модуль класов и перемкнуло! иконечно же через Workbook_SheetChange будет проще.
_Boroda_, В модуль книги еще проще ненужно с класами заморачиваться! А то я как то забыл о том что есть Workbook_SheetChange. просто писал только что код чтобы в нескольких книгах события отлавливать вот меня на модуль класов и перемкнуло! иконечно же через Workbook_SheetChange будет проще.Poltava
Poltava, запись worksheet _change, на листах, особо не напрягает. Тем более, что на разных листах, ячейки запускающие процедуру УдалениеСтрок разные. Главная задача упростить саму процедуру удаления строк и по возможности сделать так, чтобы не нужно было дописывать наименование листов на которых нужно ее запустить. По умолчанию при любом изменении назначенных ячеек все листы имеющие статус visible = true прочесывались на эту процедуру.
Добрый день,
Poltava, запись worksheet _change, на листах, особо не напрягает. Тем более, что на разных листах, ячейки запускающие процедуру УдалениеСтрок разные. Главная задача упростить саму процедуру удаления строк и по возможности сделать так, чтобы не нужно было дописывать наименование листов на которых нужно ее запустить. По умолчанию при любом изменении назначенных ячеек все листы имеющие статус visible = true прочесывались на эту процедуру.qshin1980
В ваших сообщениях не хватает самого главного - файла-примера (несколько листов с непустыми таблицами) под вновь появившиеся идеи. Еще было бы неплохо на словах пояснить что должен делать макрос "УдалениеСтрок" так как показанный код ничего не удаляет.
В ваших сообщениях не хватает самого главного - файла-примера (несколько листов с непустыми таблицами) под вновь появившиеся идеи. Еще было бы неплохо на словах пояснить что должен делать макрос "УдалениеСтрок" так как показанный код ничего не удаляет.AlexM
Номер мобильного модема (без голосовой связи) 9269171249 МегаФон, Московский регион.
Как раз сижу делаю его. Сделать пример оказалось сложнее, чем основной проект. Пытаюсь провести параллели между основными задачами и новыми яблоками и грушами)))
Как раз сижу делаю его. Сделать пример оказалось сложнее, чем основной проект. Пытаюсь провести параллели между основными задачами и новыми яблоками и грушами)))qshin1980
На листе "Assorti", есть кнопка "Изменить ассортимент". Нажимаем, получается новый лист (код наверно жутко примитивный но работает. В идеале название листа должно быть "Изменения_Клиент1", но как это сделать я не знаю). Так вот, при появлении нового листа "Изменения", т.к. он не прописан в процедуру "УдалениеСтрокПоУсловию" код на этом листе не работает. Если название листа прописывать изначально в код процедуры "УдалениеСтрокПоУсловию", то выдает ошибку при работе с остальными листами, до того как появится лист "Изменения". Я прописал в процедуру
[vba]
Код
On Error Resume Next
[/vba]
ошибку не выдает, но это не панацея.
Из этого и вопрос: как прописать процедуру "УдалениеСтрокПоУсловию", чтобы она работала на всех листах книги и независила от названия листа.
Вот что получилось
На листе "Assorti", есть кнопка "Изменить ассортимент". Нажимаем, получается новый лист (код наверно жутко примитивный но работает. В идеале название листа должно быть "Изменения_Клиент1", но как это сделать я не знаю). Так вот, при появлении нового листа "Изменения", т.к. он не прописан в процедуру "УдалениеСтрокПоУсловию" код на этом листе не работает. Если название листа прописывать изначально в код процедуры "УдалениеСтрокПоУсловию", то выдает ошибку при работе с остальными листами, до того как появится лист "Изменения". Я прописал в процедуру
[vba]
Код
On Error Resume Next
[/vba]
ошибку не выдает, но это не панацея.
Из этого и вопрос: как прописать процедуру "УдалениеСтрокПоУсловию", чтобы она работала на всех листах книги и независила от названия листа.qshin1980
For i = 3 To Sheets.Count Sheets(i).Rows.Hidden = False Next
[/vba]
А вообще [vba]
Код
Sub Мяу() Dim ra As Range, delra As Range, ТекстДляПоиска As String ТекстДляПоиска = "строку не заполнять" Application.ScreenUpdating = False For i = 3 To Sheets.Count With Sheets(i) .Rows.Hidden = False For Each ra In .UsedRange.Rows If Not ra.Find(ТекстДляПоиска, , xlValues, xlPart) Is Nothing Then If delra Is Nothing Then Set delra = ra Else Set delra = Union(delra, ra) End If If Not delra Is Nothing Then delra.EntireRow.Hidden = True Next End With Next Application.ScreenUpdating = True End Sub
For i = 3 To Sheets.Count Sheets(i).Rows.Hidden = False Next
[/vba]
А вообще [vba]
Код
Sub Мяу() Dim ra As Range, delra As Range, ТекстДляПоиска As String ТекстДляПоиска = "строку не заполнять" Application.ScreenUpdating = False For i = 3 To Sheets.Count With Sheets(i) .Rows.Hidden = False For Each ra In .UsedRange.Rows If Not ra.Find(ТекстДляПоиска, , xlValues, xlPart) Is Nothing Then If delra Is Nothing Then Set delra = ra Else Set delra = Union(delra, ra) End If If Not delra Is Nothing Then delra.EntireRow.Hidden = True Next End With Next Application.ScreenUpdating = True End Sub
скорее всего Ваш пример слабо соответствует действительности. 1)Не понятно когда должно срабатывать Worksheet_Change то есть при каких условиях 2)Непонятно почему нужно перебирать ВСЕ листы???
скорее всего Ваш пример слабо соответствует действительности. 1)Не понятно когда должно срабатывать Worksheet_Change то есть при каких условиях 2)Непонятно почему нужно перебирать ВСЕ листы???Poltava