Страницы: 1
RSS
Создание массива в макросе
 
Добрый вечер! Есть столбец с шестизначными числами, около 3500. Макрос проверяет введённое данное на соответствие с этими числами. Сделал это с помощью цикла. Знаю, что есть формулы для работы с массивом. Но для этого надо будет вручную вбивать это огромное количество кодов в макрос вручную, что нереально. Есть ли возможность сделать это, чтоб проверка на соответствие шла в самом макросе, без дополнительной активации страницы с этим массивом? Спасибо!
 
Пример файла надо.
Цитата
ELL.EMENT пишет:
введённое данное на соответствие с этими числами
введенное число проверяет?
Соответствие с чем?
Совпадает или нет с одним из других чисел в списке??
Или ищет сколько совпадений?
Ничего непонятно=)
Изменено: gaz- polutorka - 10.02.2013 11:40:48
 
А в какой момент проверяет и куда вводят данные?
Если на листе и только в одном месте то можно и формулами обойтись:)
 
Формулами можно, но нужно макросом.
Да, необходимо введённое в InputBox число сравнить, совпадает ли оно с каким либо значением из этого списка. Дело в том, что этот список в одном открытом файле, а результат, есть ли совпадение, необходимо отметить в другом файле. Вот и хотелось бы каким-либо способом вбить эти 3500 значений списка в код макроса, чтоб не обращаться к тому файлу.
 
Одним словом, как создать массив  Spisok=Аrray("000123", "000222", ...... ) из 3500 чисел этого списка не вручную?
 
Spisok=range("a1:a3500").value
Получаете двумерный массив, по которому можно быстро пробежаться циклом.
Или создать публичный словарь, и загнать один раз данные в него - тогда поиск будет вообще мнгновенным.
Ну а ещё (если данные на листе, а не в тексте ил где-то ещё) в макросе можно использовать формулу СЧЁТЕСЛИ() или ВПР() или ИНДЕКС() или что там ещё можно подыскать...
 
Или так - из текста:

Код
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.OpenTextFile("c:\Temp\список.txt", 1)    'Подставьте свой путь к txt-файлу
arrstr = Split(ts.ReadAll, vbCrLf)    'массив строк текста целикомts.Close

или короче
Код
With CreateObject("Scripting.FileSystemObject").OpenTextFile("c:\Temp\список.txt", 1)    'Подставьте свой путь к txt-файлу
arrstr = Split(.ReadAll, vbCrLf)    'массив строк текста целиком
End With
Изменено: Hugo - 07.02.2013 22:57:51
 
Можно узнать, как создаётся этот "публичный словарь"? Не придётся ли для пользования им прибегать к каким-либо дополнительным установкам непросвящённым пользователям?
 
Hugo, спасибо большое за ответ и желание помочь, но список не в текстовом файле, а в Excel.
 
Цитата
ELL.EMENT пишет:
Можно узнать, как создаётся этот "публичный словарь"?
Поищите по строке "Scripting.Dictionary".
 
Цитата
Не придётся ли для пользования им прибегать к каким-либо дополнительным установкам непросвящённым пользователям?
Нет, не придется.
Алгоритм макроса такой:
1.Открыть нужный файл, с помощью Workbook.Open
2.Объявить диапазон ячеек с нужными данными - set MyRng = range("a1:a3500" ;) .value
2.1. Загнать диапазон значений сразу в массив - MyArr = MyRng.value
2.1. Пройтись циклом по значениям диапазона и записать значения в словарь Scritping Dictionary
3.Ну, и дальнейшая Ваша обработка

Ps. Если Вы хотите, чтобы Вам быстрее помогли - выложите маленький файл-пример с данными.
Изменено: LightZ - 07.02.2013 23:39:04
Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете?
 
Спасибо всем!)
 
С публичным словарём думаю можно/нужно делать примерно так:

Код
Public oDict As Object

Sub tt()
    Dim a(), i&
    If oDict Is Nothing Then
        a = [a1].CurrentRegion.Value
        Set oDict = CreateObject("scripting.dictionary")
        For i = 1 To UBound(a): oDict.Item(a(i, 1)) = i: Next
    End If
    MsgBox oDict.Item([a2].Value)
End Sub


Так словарь будет заполняться только при первом вызове, далее он будет только отдавать данные.
Но конечно если база меняется - словарь нужно перезаполнять, иначе в нём будут устаревшие данные.
 
А эта строка MsgBox oDict.Item([a2].Value) что будет выводить на экран?

И еще вопросик
oDict.Item(a(i, 1)) = i
Правильно ли я понимаю, что в этой строке мы i-тому элементу словаря присваиваем i-тое значение массива? Тогда запись какая-то странная
Изменено: korsar75 - 08.02.2013 05:07:32
 
Код
'объявляем публичный объект -
'будет доступен всегда и всюду, пока жив Эксель
Public oDict As Object

Sub tt()
    Dim a(), i&    'объявляем переменные, ничего интеесного...
'если словарь ещё не существует
    If oDict Is Nothing Then
        'берём в массив все анализируемые номера с листа
        a = [a1].CurrentRegion.Value
        'делаем из объекта словарь
        Set oDict = CreateObject("scripting.dictionary")
        'перебираем в цикле массив (первый столбец),
        'помещаем в словарь анализируемые значения и к каждому
        'его позицию в массиве (номер строки массива)
        For i = 1 To UBound(a): oDict.Item(a(i, 1)) = i: Next
    End If

    'ну а тут просто демонстрация - имеем откуда-то значение
    '(я взял значение из A2, но может быть любой источник, например
    'введённый пользователем куда угодно - ячейка, инпутбокс, форма,
    'перебор в цикле другого массива/списка/текстового файла),
    'проверяем наличие значения в словаре, и если есть -
    'получаем номер его строки
    If oDict.exists([a2].Value) Then MsgBox oDict.Item([a2].Value)
    'по номеру строки можно получить любые другие данные этого массива

End Sub
Изменено: Hugo - 09.02.2013 03:42:03
 
Hugo Извиняюсь за назойливость, но можно поподробнее.

Вот вы пишите комментарий
'перебираем в цикле массив (первый столбец),
       'помещаем в словарь анализируемые значения и к каждому
       'его позицию в массиве (номер строки массива)
Ну понятно, что часть комента обрезалась, но это не страшно, т.к. смысл донесен. Но непонятна реализациявот этого момента: "помещаем в словарь анализируемые значения".
Вот это и есть процесс помещения значения массива в словарь: oDict.Item(a(i, 1))?

Ну а тут похоже просто ошибка:
If oDict.exists([a25].Value) Then MsgBox oDict.Item([a2].Value)
Вместо [a25] должно быть [a2], правильно? Или мы берем значение из ячейки А25 проверяем его наличие в словаре и если оно там есть, то тогда печатаем значение А2?
 
Да, с 25 ошибся - в одном месте исправил, в другом забыл...  :(
Должно быть одинаковое значение - исправил пост выше, чтоб других тоже с толку не сбивал...
Комменты вроде как не обрезались - это я так коряво выразился  :)

Вот это и есть процесс помещения значения массива в словарь: oDict.Item(a(i, 1))="любое значение"
Это альтернативный способ, в хелпе и учебниках делают иначе, но так короче  :)
Словами можно описать так - в словаре у этого значения массива будет итем такой-то.
Что подразумевает, что мы это значение с таким-то итемом туда заносим.
Есть один момент - если значение повторится, то его итем перезапишется на новый. Это в зависимости от задачи нужно учитывать.
Изменено: Hugo - 09.02.2013 03:42:47
 
Цитата
Hugo пишет:
Вот это и есть процесс помещения значения массива в словарь: oDict.Item(a(i, 1))="любое значение"
Это альтернативный способ, в хелпе и учебниках делают иначе, но так короче:)
Словами можно описать так - в словаре у этого значения массива будет итем такой-то.
Что подразумевает, что мы это значение с таким-то итемом туда заносим.
Есть один момент - если значение повторится, то его итем перезапишется на новый. Это в зависимости от задачи нужно учитывать.
Не совсем понял вашу мысль :-( Но после прочтения одного файлика, в котором написано вот это:

При задании нового значения этого свойства:
oDict.Item(<Key>) = "NewValue"
Если КЛЮЧ "Key" в словаре есть, то ассоциированное с ним ЗНАЧЕНИЕ заменяется на заданное "NewValue"
Если КЛЮЧ "Key" в словаре отсутствует, то создается новая ЗАПИСЬ с КЛЮЧОМ "Key"  и ЗНАЧЕНИЕМ "NewValue"

Многое стало на места. Т.е. вы значения массива используете как ключ. А я почему-то думал, что значение массива это просто значение, но для него должен быть какой-то ключ. Короче это все от недостатка знаний :-(
Бум будем дальше курить форум, Уокенбаха и иже с ними

Большое спасибо, стало чуть понятней
 
Ознакомьтесь с вложением, хорошо написано
Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете?
 
Ну да, ключём является само анализируемое/проверяемое/сравниваемое выражение.
Ну а ему в Item можно что-то "прикрепить" - номер строки, какой-то признак, массив значений или коллекцию, или даже другой словарь, и это "приклепление" можно оперативно менять, смотря какая стоит задача.
 
Цитата
LightZ пишет:
Ознакомьтесь с вложением, хорошо написано

Спасибо. Именно из этого файла я и взял эти строчки:

oDict.Item(<Key>) = "NewValue"
Если КЛЮЧ "Key" в словаре есть, то ассоциированное с ним ЗНАЧЕНИЕ заменяется на заданное "NewValue"
Если КЛЮЧ "Key" в словаре отсутствует, то создается новая ЗАПИСЬ с КЛЮЧОМ "Key" и ЗНАЧЕНИЕМ "NewValue"

Просто не совсем понятна была реализация в макросе Hugo. Поэтому и столько вопросов. Но с вашей помощью все стало понятно.
Страницы: 1
Читают тему
Наверх