Форум программистов, компьютерный форум, киберфорум
VBA
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.82/33: Рейтинг темы: голосов - 33, средняя оценка - 4.82
0 / 0 / 0
Регистрация: 05.11.2009
Сообщений: 15

Перенос ячеек внутри файла excel

05.11.2009, 22:18. Показов 6563. Ответов 23
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
есть таблица excel:
Лист1
столбец A: 1022 уникальных номеров (регистрационные номера банков)
Строка C3-GJ3 (около 200): разные виды счетов
ячейки C4 - GJ1022: пока пустые
Лист2 ~23000 строк
столбец A: уникальные номера (это банки, если что)
столбец B: разные виды счетов, около 200 разных
столбец C: циферки, которые должны быть перемещены(скопированы) в диапазон C4 - GJ1022

Тоже самое другими словами:
В столбце C (на втором листе) - то, что должно быть на пересечении циферок из A и B
Соответственно, на первом листе надо разместить 1022 строчки и ~200 столбцов, на пересечении которых будут данные из столбца C со второго листа
Если и так непонятно, могу выложить файлы)
Всего очень похожих задач у меня штук 10 будет, так что нужно что-то гибкое

Добавлено через 25 минут
Вот попробовал написать, но это только алгоритм, как это привязать к реальной таблице не представляю...
mas1 и mas2 - это я так представил первый и второй лист (я понимаю, что обращение производится как-то по-другому, но сейчас времени просто нет синтаксис учить).
Вопрос ещё, совсем нубский: а в vba индексы массивов с нуля или единицы начинаются?
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Sub Export()
    Dim k, n, i As Integer
    Dim mas1(1022, 1000) As Integer, mas2(3, 22907)
    For k = 1 To 1022
        For n = 1 To 22907
            If mas1(k, 1) = mas2(1, n) Then
                For i = 1 To 1000
                    If mas1(3, i) = mas2(2, n) Then
                        mas1(k, i) = mas2(3, n)
                    End If
                Next i
            End If
        Next n
    Next k
End Sub
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
05.11.2009, 22:18
Ответы с готовыми решениями:

Перенос информации из ячеек Excel в Word
Добрый день всем. Люди добрые помогите разобратся с таким заданием: Перенос текстовой и числовой информации из ячеек Excel в уже...

Построчный перенос данных из ячеек Excel в закладки Word
Добрый день, уважаемые форумчане! :) Помогите, пожалуйста, не смогла найти решения поставленной задачи. Перерыла много форумов, нашла...

Сравнение значений ячеек на разных листах Excel и их перенос
Доброго Вам времени суток, уважаемие знатоки!!! Нужна Ваша помощь и подсказки. На листе 1 есть табличка, на листе 2 есть список, нужно...

23
 Аватар для BasicMan
19318 / 2626 / 84
Регистрация: 17.02.2009
Сообщений: 30,364
05.11.2009, 22:42
Цитата Сообщение от s72068 Посмотреть сообщение
а в vba индексы массивов с нуля или единицы начинаются
а это как в Option Base задано будет 0 или 1
1
0 / 0 / 0
Регистрация: 05.11.2009
Сообщений: 15
06.11.2009, 10:25  [ТС]
Так, вот v1.2 - выдает
runtime error 9
subscript out of range
Когда добавил эту строчку
Visual Basic
1
On Error Resume Next
ошибка исчезла, появилось зависание, камень грузится ровно на 43%, выключать пока не буду - вдруг копируется)))

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Sub Export()
    Dim k, n, i As Integer
    For k = 1 To 1022
        For n = 1 To 22907
            If Worksheets("Main").Cells(k, 1) = Worksheets(List2).Cells(1, n) Then
                For i = 1 To 1000
             If Worksheets("Main").Cells(3, i) = Worksheets(List2).Cells(2, n) Then
        Worksheets("Main").Cells(k, i)= Worksheets(List2).Cells(3, n)
                    End If
                Next i
            End If
        Next n
    Next k
End Sub
В этом коде есть очевидные ошибки?
0
437 / 144 / 9
Регистрация: 12.01.2009
Сообщений: 678
Записей в блоге: 1
06.11.2009, 10:55
Цитата Сообщение от s72068 Посмотреть сообщение
Так, вот v1.2 - выдает
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Sub Export()
    Dim k, n, i As Integer
    For k = 1 To 1022
        For n = 1 To 22907
            If Worksheets("Main").Cells(k, 1) = Worksheets(List2).Cells(1, n) Then
                For i = 1 To 1000
             If Worksheets("Main").Cells(3, i) = Worksheets(List2).Cells(2, n) Then
        Worksheets("Main").Cells(k, i)= Worksheets(List2).Cells(3, n)
                    End If
                Next i
            End If
        Next n
    Next k
End Sub
В этом коде есть очевидные ошибки?
Да есть.
1-я ошибка: List2 нужно взять в кавычки.
2-я ошибка: Вылазит ошибка когда значение переменной i достигает 257. Чего на самом деле быть не может. Это связано с тем, что в экселе 2003 количество столбцов равно 256. Выход заключается в переходе к экселю 2007 или другом расположении данных.
0
0 / 0 / 0
Регистрация: 05.11.2009
Сообщений: 15
06.11.2009, 11:02  [ТС]
analyst, У меня 2007 SP2
Кавычки сделал, но я запутался: в Cells(x, y) x - это строки, а y - столбцы, или наоборот?
0
437 / 144 / 9
Регистрация: 12.01.2009
Сообщений: 678
Записей в блоге: 1
06.11.2009, 11:12
А в общем код очень не оптимизирован. Поэтому очень долго работает. Выложите файл с данными.
x-это строки, а y - это столбцы.
0
0 / 0 / 0
Регистрация: 05.11.2009
Сообщений: 15
06.11.2009, 11:56  [ТС]
Файлик больно большой, выкладываю порезанный (оставил на втором листе только 617 строк, в моем файле их 22906 и банков получилось всего штук 15, но для понимания, думаю, хватит)
Почему нельзя выкладывать *.xlsx?
Вложения
Тип файла: xls 1.xls (91.5 Кб, 75 просмотров)
0
0 / 0 / 0
Регистрация: 05.11.2009
Сообщений: 15
06.11.2009, 12:27  [ТС]
версия 1.3 вышла рабочая, проверил пока на резаном файле, все скопировал правильно. выполнялось секунд 5.
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Sub Export()
    Dim k, n, i As Integer
    For k = 4 To 21
        For n = 1 To 617
            If Worksheets("Лист1").Cells(k, 1) = Worksheets("Лист2").Cells(n, 1) Then
                For i = 1 To 192
                 If Worksheets("Лист1").Cells(3, i) = Worksheets("Лист2").Cells(n, 2) Then
                Worksheets("Лист1").Cells(k, i) = Worksheets("Лист2").Cells(n, 3)
                    End If
                Next i
            End If
        Next n
    Next k
End Sub
как зафиксировать время выполнения? понимаю, это все азы из книжек, но я только вечером поеду за литературой.
0
14 / 14 / 1
Регистрация: 03.09.2009
Сообщений: 109
06.11.2009, 13:20
s72068, если копируется диапозон ячеек, то думаю лучше использовать range.copy , range.paste

Добавлено через 29 минут
s72068, опишите условия копирования, вообщем, что должно происходите в результате выполнения..
0
0 / 0 / 0
Регистрация: 05.11.2009
Сообщений: 15
06.11.2009, 13:36  [ТС]
Chipnddail, range.copy , range.paste работают быстрее?
проверил свой скриптик в бою - выдержал, проверил случайные значения - все правильно
Условия:
Со второго листа из столбика С каждое значение должно копироваться в соответствующую ячейку на первом листе (на пересечении номера банка и номера счета, на втором листе это столбцы A, B в соответствующих строках).
Сейчас копируются ~23000 значений, уже минут 10. Я подожду, но если есть способ кардинально ускорить процесс, буду признателен за подсказку
0
437 / 144 / 9
Регистрация: 12.01.2009
Сообщений: 678
Записей в блоге: 1
06.11.2009, 14:28
Цитата Сообщение от s72068 Посмотреть сообщение
Chipnddail, range.copy , range.paste работают быстрее?
Я подожду, но если есть способ кардинально ускорить процесс, буду признателен за подсказку
Ускорить можно следующим образом.
Идёте по значениям которые вам нужно вставлять. Если на первом листе удаётся найти идентификатор банка и соответствующий счёт, то вы можете получить ячейку в которую нужо вставлять это значение. Пользоваться нужно методом find.
Так точно будет работать быстрее потому, что не нужно будет пробегать лишний раз кучу ячеек, но на сколько быстрее не знаю)
1
14 / 14 / 1
Регистрация: 03.09.2009
Сообщений: 109
06.11.2009, 15:05
Попоробуте так, должно быть быстрее.

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
Private range1 As Range
Private range2 As Range
 
Private Sub setRanges()
    Set range1 = ActiveWorkbook.Worksheets(1).Range("A1:GJ21")
    Set range2 = ActiveWorkbook.Worksheets(2).Range("A1:C617")
End Sub
 
Private Sub mySub()
    On Error GoTo ExitGo:
    Dim RowCount As Integer
    RowCount = range2.Rows.count
    Dim i As Integer
    i = 4
    Dim num As Integer
    num = Number(i)
    For Row = 1 To RowCount
        If range2(Row, 1) = num Then
            Dim colCount As Integer
            colCount = range1.Columns.count
            For col = 1 To colCount
                If range2(Row, 2) = range1(3, col) Then
                    range1(i, col) = range2(Row, 3)
                    Exit For
                End If
            Next col
        Else
            i = i + 1
            num = Number(i)
        End If
    Next Row
ExitGo:
RowCount = Empty
num = Empty
colCount = Empty
End Sub
 
Private Function Number(i As Integer) As Integer
    Number = range1(i, 1)
End Function
 
Public Sub Solve()
    Call setRanges
    Call mySub
Set range1 = Nothing
Set range2 = Nothing
End Sub
Добавлено через 16 минут
Должно работать, если только во втором листе номера банков в возрастающем порядке
Работает Быстреее???
1
0 / 0 / 0
Регистрация: 05.11.2009
Сообщений: 15
06.11.2009, 15:45  [ТС]
Chipnddail, да, действительно у меня заняло около минуты полный список раскидать.
Всем спасибо, если ни у кого предложений по оптимизации больше нет, думаю, тему можно закрывать
0
14 / 14 / 1
Регистрация: 03.09.2009
Сообщений: 109
06.11.2009, 15:55
s72068, ща погодите попробуем с find
0
437 / 144 / 9
Регистрация: 12.01.2009
Сообщений: 678
Записей в блоге: 1
06.11.2009, 16:12
Есть ещё такой вариант.
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Sub Export()
    n = 1
    Do While Sheets("Лист2").Cells(n, 3) <> Empty
        data = Sheets("Лист2").Cells(n, 3)
        bank_id = Sheets("Лист2").Cells(n, 1)
        account = Sheets("Лист2").Cells(n, 2)
        Sheets("Лист1").Activate
        'ищем строчку с банком
        Set x = Cells.Find(bank_id, lookat:=xlWhole)
        If Not x Is Nothing Then
            Cells.Find(bank_id, lookat:=xlWhole).Activate
            i = ActiveCell.Row
        Else: i = 0
        End If
        'ищем столбец со счётом
        Set y = Cells.Find(account, lookat:=xlWhole)
        If Not y Is Nothing Then
            Cells.Find(account, lookat:=xlWhole).Activate
            j = ActiveCell.Column
        Else: j = 0
        End If
        'вставляем переменную, если нашёлся соответствующий счёт и банк
        If i <> 0 And j <> 0 Then
        Sheets("Лист1").Cells(i, j) = data
        End If
    n = n + 1
    Loop
End Sub
Какой быстрее?)
0
0 / 0 / 0
Регистрация: 05.11.2009
Сообщений: 15
06.11.2009, 16:18  [ТС]
)) хм. я думаю, стоит выложить полный файл где-нибудь.
У меня тут на порядок посложнее задачка назрела, теперь у каждого банка по 12 параметров для каждого счета (всего около 3.45 млн значений), на ней будет правильнее методы проверять.
Есть мысль, что таблицу надо или 3-мерную делать, или очень большую, но тогда считать все это будет гораздо сложнее.
собственно, три оси - номера счетов, номера банков и виды валюты
Виды валюты:
рубли; драг металы+инВалюта; итого
для входящих остатков, оборотов за отчетный период по дебету и по кредиту, исходящих остатков
даже не знаю что и делать с этим кошмарищем
0
14 / 14 / 1
Регистрация: 03.09.2009
Сообщений: 109
06.11.2009, 16:28
s72068, предложенный мной Метод работает неверно
0
0 / 0 / 0
Регистрация: 05.11.2009
Сообщений: 15
06.11.2009, 16:38  [ТС]
Здесь второй файл, в нем данные только по одному банку. сделать надо примерно тоже самое.
На втором листе столбики располагаются соответственно.
Если есть мысли, как это сделать проще, я открыт для всего
Вложения
Тип файла: xls 2.xls (95.0 Кб, 43 просмотров)
0
0 / 0 / 0
Регистрация: 06.11.2009
Сообщений: 3
06.11.2009, 16:39
Можно попробовать так:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
Sub export()
 
Dim i, j, k, l As Integer
Dim c1, r1, r2 As Variant
 
c1 = 192 
r1 = 21 
r2 = 617 
 
Dim indxClmn, indxRw, expArray As Variant
 
ReDim indxClmn(4 To c1, 2) As Variant
ReDim indxRw(4 To r1, 2) As Variant
ReDim expArray(1 To r2, 3) As Variant
 
expArray = Worksheets("Лист2").Range(Cells(1, 1), Cells(r2, 3))
 
For i = 4 To c1
    indxClmn(i, 1) = Worksheets("Лист1").Cells(3, i).Value
    indxClmn(i, 2) = Worksheets("Лист1").Cells(3, i).Column
Next i
 
For i = 4 To r1
    indxRw(i, 1) = Worksheets("Лист1").Cells(i, 1).Value
    indxRw(i, 2) = Worksheets("Лист1").Cells(i, 1).Row
Next i
 
For i = 1 To r2
 
    For j = LBound(indxClmn) To UBound(indxClmn)
        
        If expArray(i, 2) = indxClmn(j, 1) Then
        k = indxClmn(j, 2)
        Exit For
        End If
    Next j
    
    For j = LBound(indxRw) To UBound(indxRw)
        
        If expArray(i, 1) = indxRw(j, 1) Then
        l = indxRw(j, 2)
        Exit For
        End If
    
    Next j
    
    Worksheets("Лист1").Cells(l, k) = expArray(i, 3)
    
Next i
End Sub
Это к первому варианту.
0
14 / 14 / 1
Регистрация: 03.09.2009
Сообщений: 109
06.11.2009, 17:12
Вот моя обновленная процедура
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
    On Error GoTo ExitGo:
    Dim RowCount As Integer
    RowCount = range2.Rows.Count
    Dim bankcount  As Integer
    bankcount = range2.Rows.Count
    Dim i As Integer
    i = 4
    Dim num As Integer
    num = Number(i)
    For Row = 1 To RowCount
        Do While num <> range2(Row, 1)
            i = i + 1
            If i > bankcount Then
                GoTo ExitGo:
            Else
                num = Number(i)
            End If
        Loop
        Dim colCount As Integer
        colCount = range1.Columns.Count
        For col = 1 To colCount
            If range2(Row, 2) = range1(3, col) Then
                range1(i, col) = range2(Row, 3)
                Exit For
            End If
        Next col
    Next Row
ExitGo:
RowCount = Empty
num = Empty
colCount = Empty
bankcount = Empty
End Sub
Вроде корректно работает, проверьте

А на счет скорости замерил с помощью QueryPerformanceFrequency , QueryPerformanceCounter
И результат удивил, даже меня моя процедура : 1,822 сек
процедура analyst 3,238 сек!!
Думал, что у analyst быстее, ан нет???!!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
06.11.2009, 17:12
Помогаю со студенческими работами здесь

Перенос данных из ячеек таблицы Excel в соответствующие ячейки шаблона Word
Здравствуйте !Передо мной на производственной практике поставили задачу:есть заполненная таблица Excel и есть файл Word,в котором...

Перенос ячеек на новые страницы, excel
Ребят, подскажите пожалуйста, Есть таблица в эксель с данными, на каждую строку нужно создать новую страницу (с одним и тем же текстом) и...

Перенос заливки из ячеек excel в ячейки Access
Привет, коллеги! Есть проблема: перенести заливку из EXCEL в Access.

Перенос данных из ячеек html таблицы в таблицу Excel
есть таблица из которой мне надо взять данные ячеек и перенести их в заполненный Excel. данные выводить не хочет либо ошибку выдает либо...

Перенос данных из Excel или таблицы Word в DataGridView простым копированием ячеек
Нигде не могу найти, как организовать перенос данных из Excel или таблицы Word в DataGridView простым копированием ячеек. Может кто...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru