"отследить" правильность ввода данных

Весь MS Office, программирование на Visual Basic for Applications и MS VB

Модератор: Naeel Maqsudov

Аватара пользователя
VictorM
Сообщения: 794
Зарегистрирован: 23 окт 2006, 01:44
Откуда: Lugansk, Ukraine
Контактная информация:

Здравствуйте, уважаемые!
На сей раз у меня такой вопрос:
есть лист заполненный формулой типа ИНДЕКС, ПОИСКПОЗ. Ячеек несколько тысяч, защитить лист от ручного ввода нельзя по условию (пользователь хочет иногда редактировать данные). Можно ли как то отразить на листе, допустим с помощью другого формата, как были получены данные - формулой или введены вручную?
Спасибо.
Аватара пользователя
Aent
Сообщения: 1129
Зарегистрирован: 01 окт 2006, 14:52
Откуда: Saratov,Russia
Контактная информация:

Элементарно c помощью обработчика событий

Код: Выделить всё

Private Sub Worksheet_Change(ByVal Target As Range)
    If Left$(Target.FormulaArray, 1) = "=" Then
        Target.Interior.Color = 16777164
    ElseIf Left$(Target.Formula, 1) = "=" Then
        Target.Interior.Color = 16777164
    End If
End Sub
Аватара пользователя
VictorM
Сообщения: 794
Зарегистрирован: 23 окт 2006, 01:44
Откуда: Lugansk, Ukraine
Контактная информация:

Aent, спасибо за столь быстрый ответ, но я чего - то не въеду, куда этот обработчик вставить. В на лист или в стандартный модуль. (пока что ни там ни там не работает).
И еще попутно, если таких листов несколько - как быть?
Спасибо.
P.S. не в стандартный модуль - однозначно, разобрался. Но и в модуле листа нет реакции на событие. Пока не разберусь.
Аватара пользователя
Aent
Сообщения: 1129
Зарегистрирован: 01 окт 2006, 14:52
Откуда: Saratov,Russia
Контактная информация:

&quot писал(а):я чего - то не въеду, куда этот обработчик вставить.
:( :(
Естественно, обработчик ОДНОГО листа вставляется в код макросов листа.
Для всей книги обработчик, опять же естественно, вставляется в код
"ЭтаКнига" (ThisWorkbook)

Код: Выделить всё

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
....
end sub
Здесь Sh это в частном случае Worksheet. Проверяйте имя и обрабатывайте для
тех листов где надо.
Аватара пользователя
VictorM
Сообщения: 794
Зарегистрирован: 23 окт 2006, 01:44
Откуда: Lugansk, Ukraine
Контактная информация:

Aent, пока я "излагал" свои P.S., Вы уже мне ответили :-), спасибо.
Буду пробовать.
P.S.2. работает, в условии ElseIf нужно написать <> "=" ну и цвет поменять.
Только вот заморочка, обработчик реагирует на события, которые происходят после того как он (обработчик) появился в книге т.е. с текущего времени, а то, что было введено ранее никак не отслеживается.
А тут задачка такая, чтобы можно было просмотреть в уже существующей книге, что было внесено формулой, а что вручную.
Аватара пользователя
Aent
Сообщения: 1129
Зарегистрирован: 01 окт 2006, 14:52
Откуда: Saratov,Russia
Контактная информация:

&quot писал(а):в условии ElseIf нужно написать <> "="
1) Если вы хотите раскрасить ячейки с формулами то именно = "=" а не <> "="
Первый IF проверяет формулу массива, второй - скалярную формулу.
2) Ничто не мешает написать макрос который пройдётся по всем листам активной книги и проанализировав ячейки описанным выше образом не поменяет их формат. Можно посадить такой макрос на смену активного листа и обрабатывать только лист
принимающий активность.
Позволю себе маленький совет:
Developer, познакомтесь с cобытийной моделью Excel и свойствами Range ;)
Avsha
Сообщения: 665
Зарегистрирован: 08 сен 2005, 13:47
Откуда: KZ

а если использовать стандартный механизм Excel???
меню Файл\Правка\Перейти\ кнопка Выделить\Формулы

макрорекордер запишет при этом...
-------------------------------------

Код: Выделить всё

Sub Макрос1()
'
' Макрос1 Макрос
' Макрос записан 18.11.2007 (HomePC)
'
    Selection.SpecialCells(xlCellTypeFormulas, 23).Select
    
    Selection.Interior.Color = 16777164
End Sub

Для нескольких листов будет так...
-------------------------------------

Код: Выделить всё

Sub Макрос2()
'
' Макрос2 Макрос
' Макрос записан 18.11.2007 (HomePC)
'
    Sheets(Array("Лист1", "Лист2")).Select
    Sheets("Лист1").Activate
    Selection.SpecialCells(xlCellTypeFormulas, 23).Select
    
    Selection.Interior.Color = 16777164
End Sub

А может лучше не выделять ячейки другим форматом (чтобы не утомлять свои глаза поиском)

А просто делать проверку на наличие введеных вместо формул значений в указанном диапазоне (думаю он у вас явно как-то определен??)
и выводить результат в MsgBox или переходить на первое неформульное значение.

Код: Выделить всё

Sub Проверка()
' Проверить диапазон на неформульные значения
On Error GoTo err1

    Dim r1 As Range
    Dim r2 As Range
    
    Set r1 = Range("Name_r1")
    Set r2 = r1.SpecialCells(xlCellTypeConstants, 23)
    
    r2.Select
        
Exit Sub
err1:
   MsgBox "Проверка диапазона на неформульные значения завершено успешно !"

End Sub
Аватара пользователя
VictorM
Сообщения: 794
Зарегистрирован: 23 окт 2006, 01:44
Откуда: Lugansk, Ukraine
Контактная информация:

Всем спасибо, буду добиваться того, что мне нужно.
А нужно мне все-таки, чтобы ячейки в которые данные внесены вручную, были выделены. Неважно как.
Аватара пользователя
Aent
Сообщения: 1129
Зарегистрирован: 01 окт 2006, 14:52
Откуда: Saratov,Russia
Контактная информация:

Avsha, Да что то я стормозил насчёт SpecialCells :(
Аватара пользователя
VictorM
Сообщения: 794
Зарегистрирован: 23 окт 2006, 01:44
Откуда: Lugansk, Ukraine
Контактная информация:

В общем задачка была решена так:
На основе процедуры от Aent создана функция:

Код: Выделить всё

Public Function ValRange(ByVal Target As Range)
    If Left$(Target.FormulaArray, 1) = "=" Then
        ValRange = False
    ElseIf Left$(Target.Formula, 1) <> "=" Then
        ValRange = True
    End If
End Function
и затем эта функция была исползована в качестве условия при условном форматировании ячеек листа.
Не знаю, может что и не по правилам, но работает это так как мне нужно - выделяет ячейку с данными введеными вручную.
(Хотя стало несколько "тормозить".)
Спасибо всем за помощь.
Avsha, Ваш совет мне тоже как всегда пригодился, я использовал Вашу идею в другом месте и очень кстати :)
Ответить