Хитрости »
Основные понятия (23)
Сводные таблицы и анализ данных (9)
Графики и диаграммы (5)
Работа с VB проектом (12)
Power BI и Power Query (14)
Условное форматирование (5)
Списки и диапазоны (5)
Макросы(VBA процедуры) (63)
Разное (38)
Баги и глюки Excel (2)

Пустая ячейка определяется Excel-ем как не пустая. Что за глюк?

Эта статья будет близка тем, кому приходится часто работать с отчетами, выгруженными в Excel из программ вроде 1С, SAP и им подобных.
Вводные данные: есть отчет который выкачивается из сторонней программы. В нем есть ячейки, с виду пустые: в них нет пробелов, нет переносов на строки, никаких символов, нет объектов, условного форматирования, в настройках не стоит скрывать нули(Файл -Параметры -Дополнительно -Показывать нули в ячейках, которые содержат нулевые значения). Даже если перейти в режим редактирования ячейки - там пусто.
Если попробовать найти такие "пустые" ячейки(выделить все ячейки листа -F5 -Выделить -Пустые ячейки) - они не выделяются. Но фильтр при этом их видит как пустые и фильтрует как пустые.
Любые математические действия(умножение на ячейку, сложение, деление и т.п.) внутри формул с такими ячейками выдают ошибку #ЗНАЧ!(#VALUE!), а функция ЕПУСТО(ISBLANK) считает ячейку не пустой. Формулы вроде СУММ(SUM) и СЧЁТ(COUNT) игнорируют такие ячейки, а СЧЁТЗ(COUNTA) считает их заполненными.

И самое удивительное - если выделить такую ячейку вручную и нажать Delete (или вкладка Главная -группа Редактирование -Очистить содержимое) - то ячейка становится действительно пустой и с ней начинают работать формулы и другие функции Excel как с реально пустой.
Здесь возникает главный вопрос: что с этой ячейкой не так, если там и до Delete ничего не было?
А не так с ней вот что: практически во всех программах есть такое понятие строковых(текстовых) данных, как строка нулевой длины(еще её часто называют нулевая строка. В Visual Basic for Application такая строка обозначается константой vbNullString, в ячейках её можно встретить как сочетание двух кавычек подряд - ""). Визуально такой текст себя никак не проявляет, однако это все же текст. А любой текст это уже не пусто, но и не число.
Откуда может появится такой текст в ячейках? Здесь несколько вариантов:

  1. Он есть в ячейках изначально, потому что именно так настроена выгрузка и создание файлов в сторонней программе(вроде 1С). В некоторых случаях такие выгрузки настроены таким образом, что как таковых пустых ячеек нет - они просто заполняются строкой нулевой длины.
  2. в ячейке была записана формула, результатом которой стал текст нулевой длины. Самый простой пример такой формулы:
    =ЕСЛИ(A1=1;10;"")
    =IF(A1=1,10,"")

    в итоге, если в ячейке A1 записано любое значение, отличное от 1 формула вернет строку нулевой длины. И если впоследствии формулу заменять значением(Как удалить в ячейке формулу, оставив значения?), то получим нашу псевдо пустую ячейку.
    Если формулы создаются Вами и в дальнейшем планируются производить с этими ячейками математические действия, то лучше вместо "" ставить 0. Тогда проблем не будет. Нули всегда можно заменить или скрыть: Файл -Параметры -Дополнительно -Показывать нули в ячейках, которые содержат нулевые значения

А если такой файл делали не Вы - он достался "по наследству" или это выгрузка из другой программы, что делать тогда? Я предлагаю такой вот нехитрый код, который во всех выделенных ячейках заменит строки нулевой длины на нормальные пустые ячейки:

Sub ReplaceNullString()
    Dim rR As Range, rF As Range, rC As Range
    Dim avR, lr As Long, lc As Long
 
    Set rR = Intersect(ActiveSheet.UsedRange, Selection)
    On Error Resume Next
    Set rR = rR.SpecialCells(xlCellTypeConstants)
    On Error GoTo 0
    If rR Is Nothing Then
        MsgBox "В выделенных ячейках нет значений!", vbInformation, "www.excel-vba.ru"
        Exit Sub
    End If
    Set rF = rR.Find(vbNullString, , xlFormulas, xlWhole)
    If Not rF Is Nothing Then
        avR = rR.Value
        For lr = 1 To UBound(avR, 1)
            For lc = 1 To UBound(avR, 2)
                If avR(lr, lc) = "" Then rR.Item(lr, lc).Value = Empty
            Next lc
        Next lr
        MsgBox "Строки нулевой длины заменены", vbInformation, "www.excel-vba.ru"
        Exit Sub
    End If
    MsgBox "Строк нулевой длины на листе нет или лист защищен", vbInformation, "www.excel-vba.ru"
End Sub

Как это работает:
если раньше никогда не работали с макросами, то рекомендую ознакомиться со статьями:
Что такое макрос и где его искать?
Что такое модуль? Какие бывают модули?

  1. создаем в книге новый стандартный модуль: Alt+F11 -Insert -Module()
  2. копируем в созданный модуль приведенный выше код
  3. выделяем нужный диапазон(если надо заменить на всем листе - то можно выделить все ячейки листа или целиком нужные столбцы - программа сама определить нужные данные)
  4. нажимаем Alt+F8 и в появившемся окне выбираем ReplaceNullString
  5. Короткая видеоинструкция:
    Вставка кода в файл и его выполнение


Статья помогла? Поделись ссылкой с друзьями!
  Плейлист   Видеоуроки

Поиск по меткам

Access apple watch Multex Outlook Power Query и Power BI VBA работа в редакторе VBA управление кодами Бесплатные надстройки Дата и время Диаграммы и графики Записки Защита данных Интернет Картинки и объекты Листы и книги Макросы и VBA Надстройки Настройка Печать Поиск данных Политика Конфиденциальности Почта Программы Работа с приложениями Работа с файлами Разработка приложений Сводные таблицы Списки Тренинги и вебинары Финансовые Форматирование Формулы и функции Функции Excel Функции VBA Ячейки и диапазоны акции MulTEx анализ данных баги и глюки в Excel ссылки
Обсуждение: 6 комментариев
  1. Excell 2010 выдаёт сообщение об ошибке:
    Run-time error '13'
    Type mismatch
    Данное сообщение появляется в строке:
    For lr = 1 To UBound(avR, 1)

    • Олег, скорее всего на листе всего одна ячейка со значением, без формул.

    • Олег, скорее всего на листе всего одна ячейка со значением, без формул.
      По идее можно вот эти строки

      If Not rF Is Nothing Then
              avR = rR.Value

      заменить на такие:

      If Not rF Is Nothing Then
         avR = rR.Value
         If Not IsArray(avR) Then
             Redim avR(1 to 1, 1 to 1)
             avR(1,1) = rR.Value
         end if

      Это должно решить проблему

  2. Сергей:

    А есть какое то ограничение по количеству выделенных столбцов? Выделил около 200 - макрос после запуска сразу выдал, что заменено, но по факту ничего не поменялось. Выделил 5 столбцов - все хорошо. Excel 2010.

  3. Елизавета:

    Класс! Безотказно. Спасибо большое за код

  4. Мурат:

    К сожалению не помогло. Пытался и с первоначальным кодом и с поправкой к нему. И макросы включил в параметрах безопасности и книгу сохранил с поддержкой макросов. Жаль. Программа видит эти якобы пустые ячейки. Мне нужно было обработать данные в программе SPSS. Она их видит и считает :(

Поделитесь своим мнением

Комментарии, не имеющие отношения к комментируемой статье, могут быть удалены без уведомления и объяснения причин. Если есть вопрос по личной проблеме - добро пожаловать на Форум


Для оформления сообщений Вы можете использовать следующие тэги:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Тренинги

Заказать
Юридическая информация

Использование материалов сайта

Политика Конфиденциальности

ИП Щербаков Дмитрий Валентинович
ОГРНИП: 318502700083307
ИНН: 504013350772

Наши партнеры

Перейти
Перейти

Счетчики

Рейтинг@Mail.ru Яндекс.Метрика
© 2018 Excel для всех   Войти