Модераторы: Akina
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Перенос БД в Access из Excell... читайте в теме 
:(
    Опции темы
krulik
Дата 11.2.2006, 13:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 132
Регистрация: 14.1.2006
Где: Украина, Житомир

Репутация: нет
Всего: 4



Просьба к модераторам! Прочитайте тему а потом переносите если захотите!
Долго думал в какоом подфоруме создать тему . И решил в двух одну тут а вторую в программинге на VBA.
Теперь что мне нужно сделать.
На днях предоставили мне екселевский файлик. Структура такая.
Лист1 на нем такие поля:
  • Код предприятия
  • Название
  • Адрес
Лист2 на нем следующие поля:
  • Название
  • Телефон
  • Директор
  • и другая фигня....
Теперь немного пояснения поле Код предприятия на Листе1 содержит уникальный идентификатор каждого предприятия. На листе1 7400 записей. На листе2 11100 записей.
Теперь непосредственно зачем я это все писал.
Вы себе представили эти объемы! Я был в шоке от того что люди вели такую базу в екселе. Обратились ко мне вот с каким вопросом. В определенный момент им понадобилось чтобы в листе2 появился адрес предприятия (а он находится в Листе1)! Вот такая задача.
Первая идея напистаь на VBA что-то. (но на нем я не писал. Зато есть опыт Дельфи, С++, ну РНР учу сейчас). Сел почитал пол часа справку и написал за 10 минут вот что:
Код

Private Sub CommandButton1_Click()
 For rName = 1 To 11000 Step 1
  For rID = 1 To 7346 Step 1
   If Worksheets("name").Cells(rName, 1).Value = Worksheets("id").Cells(rID, 2) Then
      Worksheets("name").Cells(rName, 5).Value = Worksheets("id").Cells(rID, 1)
      Exit For
  End If
 Next rID
 Next rName
End Sub

В результате на моей машине (Pentium IV 3Ghz/2Mb и 512 оперативки) ушел почти час чтобы с листа1 выбрать данные в лист2 (я ячейки сравнивал по названию предприятия). Но когда я показал результат сказали что есть еще похожие листы! И тут я решил сделать им БД чтобы мне мозги не парили больше.

В Аксес я втянул эти два листа в виде двух независимых таблиц. Подскажите как мне из первой таблицы перенести Коды предприятий во вторую таблицу (естествеено сравнивать прийдется по названиям предприятий)!? Еще одно замечание не все предприятия которые есть во второй таблице есть в первой (если читали начало то заметили что в первом листе 7400 записей а во втором 11100 (получается не для всех предприятий есть Кода).
Может вот так понятние будет. Изначально после импорта данных из Екселя в Аксес схема данных вот такая:
user posted image

Мне нужно получить вот такую:
user posted image


Если непонятно изложил какието моменты то спрашивайте. Оч нужно решить эту проблему.

Вот тема созданая в разделе посвященном программингу на VBA с этой задачей

Это сообщение отредактировал(а) krulik - 11.2.2006, 15:22
--------------------
Каждый день несет в себе частицу вечности (Паоло Коэльо)Если вам плюют в спину, значит вы в переди! (Конфуций)Все, что имеет форму, может исчезнуть в одно мгновение (Харуки Мураками)
PM MAIL ICQ   Вверх
Alexandr87
Дата 11.2.2006, 14:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


дыкий псых
***


Профиль
Группа: Завсегдатай
Сообщений: 1459
Регистрация: 27.11.2004
Где: Алматы, Казахстан

Репутация: 1
Всего: 39



Я бы сделал опять в экселе, но прямой перебор это действительно - не рационально. Я бы использовал алгоритм бинрного поиска отсортированных данных
PM Jabber   Вверх
krulik
Дата 11.2.2006, 15:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 132
Регистрация: 14.1.2006
Где: Украина, Житомир

Репутация: нет
Всего: 4



Alexandr87, а можно поподробнее про твою идею только вот тут в этой теме с этой же задачей.
--------------------
Каждый день несет в себе частицу вечности (Паоло Коэльо)Если вам плюют в спину, значит вы в переди! (Конфуций)Все, что имеет форму, может исчезнуть в одно мгновение (Харуки Мураками)
PM MAIL ICQ   Вверх
Alexandr87
Дата 11.2.2006, 18:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


дыкий псых
***


Профиль
Группа: Завсегдатай
Сообщений: 1459
Регистрация: 27.11.2004
Где: Алматы, Казахстан

Репутация: 1
Всего: 39



Суть бинарного поиска
имеем данные 3,2,5,7,1,9
искать можно прямым перебором сравнивая искомый элемент с каждым в ряду, начиная с первого до последного. этот метод подходит при необльших объемах данных в ряду в котором производиться поиск.
В библиотеках напрмер существует алфавитный каталог, искать по которому очень легко, а вот без него было бы почти невозможно.
Эту же схему можно воплотить и здесь.
Сортируем данные по возрастанию 1,2,3,5,7,9
теперь ищем в данном ряду, используя,так называемый бинарный поиск. Находим средний элемент ряда, в данном случае (3) и сравниваем с искомым: если искомый элемент больше текущего серединного элемента, то отсекаем верхнуюю часть (1,2,3) и повторяем операцию, если искомый элемент меньше отсекаем нижнюю часть. Если искомый элемент равен, то считаем, что нашли. При больших объемах данных в которых надо производить поиск дает потрясающие результаты по-сравнению с "прямым"

Ниже эта идея реализована. Предпологается, что имеется 4 листа ("id","2","3","4"). Лист id - твой первый лист, лист 2 - это твой второй лист, листы 3 и 4 для записи результатов (на лист 3 записываются найденные, на лист 4 не найденные). Кнопка из которой происходит вызов процедуры располагается на листе "2". В коде есть секция, где уже происходит запись результатов на листы - я незнаю структуру по-этому дополнишь сам.
Будут вопросы - всегда рады.

Код

Option Explicit

Private Sub CommandButton1_Click()
Dim rc As Long
Dim toFind As String
Dim temp As String

Dim upR As Long
Dim dnR As Long
Dim mdR As Long
Dim count As Long
Dim checkFound As Boolean

Dim res1 As Long
Dim res2 As Long
res1 = 1
res2 = 1



With Worksheets("id")
    count = 1
    Do While (.Cells(count, 1) <> "")
        count = count + 1
    Loop
    count = count - 1
    rc = 1
    'Binary search
    Do While (Cells(rc, 1) <> "")
        checkFound = False
        upR = 1
        dnR = count
        toFind = Cells(rc, 1)
        Do While ((dnR >= upR) And Not checkFound)
            mdR = (upR + dnR) \ 2
            temp = .Cells(mdR, 2)
            If (temp = toFind) Then
                checkFound = True
            ElseIf (temp < toFind) Then
                upR = mdR + 1
            Else
                dnR = mdR - 1
            End If
        Loop
        'Check results
        If (checkFound) Then
            'If we found it write record to 3d worksheet
            Worksheets("3").Cells(res1, 1) = Cells(rc, 1)
            Worksheets("3").Cells(res1, 2) = Cells(rc, 2)
            'etc
            res1 = res1 + 1
        Else
            'If we not found it write record to 4d worksheet
            Worksheets("4").Cells(res2, 1) = Cells(rc, 1)
            Worksheets("4").Cells(res2, 2) = Cells(rc, 2)
            'etc
            res2 = res2 + 1
        End If
        rc = rc + 1
    Loop

End With

End Sub


ЗЫ. Не забудь отсортировать данные по на первом листе

Это сообщение отредактировал(а) Alexandr87 - 11.2.2006, 18:26
PM Jabber   Вверх
krulik
Дата 12.2.2006, 10:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 132
Регистрация: 14.1.2006
Где: Украина, Житомир

Репутация: нет
Всего: 4



Ну раз такое дело то вот вопрос первый.
Может я невнимательно смотрел!?
А в каком участке кода происходит непосредственно сравнение строки с Листа2 со строками в Листе2.

Я нашел только обращение к первому листу
Код

With Worksheets("id")

Ну и вконце к 3 и 4 листам.

Или вот эта строка отвечает за выбор строк с Листа2 (на котором кнопка)
Код

Do While (Cells(rc, 1) <> "")

Тоесть если явно не указывать имя листа то обращение происходит к листу с которого вызывается текущий обработчик? Я правильно понял?

Обращение к Alexandr87 еслибы я мог повышать репутацию то я бы это обязательно сделал!!! Все работает! На выполнение операции на Атлоне 1,66Ггц, 256 Мб уходит до 15секунд!!! smile

Я вот сижу пошагово прохожусь по коду. Хочу разобраться как он работает. У меня опять вопрос.
Код

Do While ((dnR >= upR) And Not checkFound)
            mdR = (upR + dnR) \ 2
            temp = .Cells(mdR, 2)
            If (temp = toFind) Then
                checkFound = True
            ElseIf (temp < toFind) Then
                upR = mdR + 1
            Else
                dnR = mdR - 1
            End If

В этом участке кода происходит постоянное деление диапозона пополам (в том случае если элемент не найден)? И потом полученном диапазоне происходит поиск?

ЗЫ: напиши в личку (чтобы тут не засорять тему) если знаешь какаето хорошие мануалы по VBA (где взять). Так как чувствую прийдется мне с ним сталкиваться еще!

Это сообщение отредактировал(а) krulik - 12.2.2006, 10:57
--------------------
Каждый день несет в себе частицу вечности (Паоло Коэльо)Если вам плюют в спину, значит вы в переди! (Конфуций)Все, что имеет форму, может исчезнуть в одно мгновение (Харуки Мураками)
PM MAIL ICQ   Вверх
Alexandr87
Дата 12.2.2006, 15:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


дыкий псых
***


Профиль
Группа: Завсегдатай
Сообщений: 1459
Регистрация: 27.11.2004
Где: Алматы, Казахстан

Репутация: 1
Всего: 39



Цитата

With Worksheets("id")

Эта конструкция, служит для упрощения написания кода. Допустим если много раз нужно обращаться к методам одного и того же объекта.

Например код
Код

worksheets("id").cells(3,3).value=2
worksheets("id").cells(4,4).value=3


можно заменить следующим
Код

with worksheets("id")
    .cells(3,3).value=2
    .cells(4,4).value=3
end with

Конечно, в данном примере и в скрипте это не суть важно, но кроме этого, он немного увеличивает скорость обрабоки.

Цитата(krulik @ 12.2.2006, 10:28 Найти цитируемый пост)

Тоесть если явно не указывать имя листа то обращение происходит к листу с которого вызывается текущий обработчик? Я правильно понял?

да



Цитата(krulik @ 12.2.2006, 10:28 Найти цитируемый пост)
ЗЫ: напиши в личку (чтобы тут не засорять тему) если знаешь какаето хорошие мануалы по VBA (где взять). Так как чувствую прийдется мне с ним сталкиваться еще!

ето форум, и на вопросы здесь принято отвечать непосредственно на форуме, думаю, что тема не очень засорится.
Единственный нормальный мануал, который я видел, это встроенный в офис хелп.

PM Jabber   Вверх
Papirus
Дата 13.2.2006, 09:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 298
Регистрация: 19.4.2005
Где: Санкт-Петербург

Репутация: 2
Всего: 1



Цитата(krulik @ 11.2.2006, 13:10 Найти цитируемый пост)
Вы себе представили эти объемы! Я был в шоке от того что люди вели такую базу в екселе.

Это не объемы - это фигня. Вот когда места на листах не хватает и периодически надо сбрасывать в архив...

Если я правильно понял задачу - решается она в екселе примитивно просто - подстановкой столбца с функцией "=ИНДЕКС()", в которую вложена функция "=ПОИСКПОЗ()" для определения номера искомой строки.
Советую копнуть в этом направлении. И программить ничего не надо! smile
PM MAIL ICQ   Вверх
Akina
Дата 13.2.2006, 09:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 30
Всего: 454



Но вообще ведение списков в тысячи позиций - не для Экселя.
По-моему пора переводить это на подходящий инструмент. В данном случае именно Аксесс.

smile Судя по описанию, такую базу более-менее соображающий в этом деле программист сделает за 2 вечера. А если без пива - то за один.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Papirus
Дата 13.2.2006, 09:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 298
Регистрация: 19.4.2005
Где: Санкт-Петербург

Репутация: 2
Всего: 1



Цитата(Akina @ 13.2.2006, 09:27 Найти цитируемый пост)
А если без пива - то за один.

Без пива ошибки недопития могут быть! smile
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "MS Access"
Akina
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • Используйте теги [code=vb][/code] и [code=sql][/code] для подсветки кода. Используйтe чекбокс "транслит" (возле кнопок кодов) если у Вас нет русских шрифтов.

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Akina.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MS Access | Следующая тема »


 




[ Время генерации скрипта: 0.0710 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.