Sub Копирование() Dim iBeginRange As Object, lCalc As Long, avArr, lr As Long, t As Single, cell, last As Range Dim sRngAddress As String, oAwb, j As String, sCopyAddress As String, sSheetName As String Dim lLastrow As Long, lLastRowMyBook As Long, li As Long, iLastColumn As Integer Dim wsSh As Object, wsDataSheet As Object, bPolyBooks As Boolean, avFiles If MsgBox("Выбрать файлы из которых будет формироваться ОС 14?", vbInformation + vbYesNo, "Excel-VBA") = vbYes Then avFiles = Application.GetOpenFilename("Excel files(*.xls*),*.xls*", , "для заполнения", , True) If VarType(avFiles) = vbBoolean Then Exit Sub t = Val(InputBox("Введите расчётный курс валюты", "курс евро")) If t = 0 Then t = 1 bPolyBooks = True Else avFiles = Array(ThisWorkbook.FullName) End If With Application lCalc = .Calculation .ScreenUpdating = False: .EnableEvents = False: .Calculation = xlManual End With Set wsDataSheet = ThisWorkbook.ActiveSheet For li = LBound(avFiles) To UBound(avFiles) If bPolyBooks Then Workbooks.Open Filename:=avFiles(li) oAwb = Dir(avFiles(li), vbDirectory) Workbooks(oAwb).Sheets("Attachment to Invoice").Activate avArr = Range("C4:N2000").Value 'выбор диапозона значений в исходном листе For lr = 1 To UBound(avArr, 1) For i = 9 To 2000 If ThisWorkbook.Sheets("Лист2").Cells(i, 1) = "" Then ThisWorkbook.Sheets("Лист2").Cells(i, 1) = avArr(lr, 8) ThisWorkbook.Sheets("Лист2").Cells(i, 35) = avArr(lr, 4) ThisWorkbook.Sheets("Лист2").Cells(i, 17) = avArr(lr, 5) ThisWorkbook.Sheets("Лист2").Cells(i, 53) = avArr(lr, 11) ThisWorkbook.Sheets("Лист2").Cells(i, 59) = avArr(lr, 12) i = i + 1: Exit For End If Next i Next lr
Next
If bPolyBooks Then Workbooks(oAwb).Close False Range("Q9:Q1000").Replace What:="m", Replacement:="м", LookAt:=xlWhole Range("Q9:Q1000").Replace What:="pc", Replacement:="шт", LookAt:=xlWhole Range("Q9:Q1000").Replace What:="set", Replacement:="компл", LookAt:=xlWhole For Each cell In Range("BA9:BA1000") If IsNumeric(cell.Value) And cell.Value <> "" Then ' Умножаются только ячейки, содержащие числовые данные cell.Value = cell.Value * t
End If Next
For Each cell In Range("BG9:BG1000") If IsNumeric(cell.Value) And cell.Value <> "" Then ' Умножаются только ячейки, содержащие числовые данные cell.Value = cell.Value * t
End If Next End Sub
[/vba]
У меня получился вполне работоспособный макрос, не без вашего участия сильные мира сего,конечно. Буду рад предложениям по оптимизации данного кода. Выложить могу только файл из которого собираются данные, файл В КОТОРЫЙ они собираются выложить не могу потому что в оригинале он весит 318кб, а WinRar напрочь отказывается уложить его в заявленные 100Кб. Но думаю если макрос вставить в любой, даже новый документ проблем вроде бы возникнуть не должно......
Я ведь просил - оформлять код тегами! если непонятно - кнопочка соответствующая есть, с решёточкой! Ну заодно ещё и отступы расставил, а то читать невозможно... Модератор.
[vba]
Code
Sub Копирование() Dim iBeginRange As Object, lCalc As Long, avArr, lr As Long, t As Single, cell, last As Range Dim sRngAddress As String, oAwb, j As String, sCopyAddress As String, sSheetName As String Dim lLastrow As Long, lLastRowMyBook As Long, li As Long, iLastColumn As Integer Dim wsSh As Object, wsDataSheet As Object, bPolyBooks As Boolean, avFiles If MsgBox("Выбрать файлы из которых будет формироваться ОС 14?", vbInformation + vbYesNo, "Excel-VBA") = vbYes Then avFiles = Application.GetOpenFilename("Excel files(*.xls*),*.xls*", , "для заполнения", , True) If VarType(avFiles) = vbBoolean Then Exit Sub t = Val(InputBox("Введите расчётный курс валюты", "курс евро")) If t = 0 Then t = 1 bPolyBooks = True Else avFiles = Array(ThisWorkbook.FullName) End If With Application lCalc = .Calculation .ScreenUpdating = False: .EnableEvents = False: .Calculation = xlManual End With Set wsDataSheet = ThisWorkbook.ActiveSheet For li = LBound(avFiles) To UBound(avFiles) If bPolyBooks Then Workbooks.Open Filename:=avFiles(li) oAwb = Dir(avFiles(li), vbDirectory) Workbooks(oAwb).Sheets("Attachment to Invoice").Activate avArr = Range("C4:N2000").Value 'выбор диапозона значений в исходном листе For lr = 1 To UBound(avArr, 1) For i = 9 To 2000 If ThisWorkbook.Sheets("Лист2").Cells(i, 1) = "" Then ThisWorkbook.Sheets("Лист2").Cells(i, 1) = avArr(lr, 8) ThisWorkbook.Sheets("Лист2").Cells(i, 35) = avArr(lr, 4) ThisWorkbook.Sheets("Лист2").Cells(i, 17) = avArr(lr, 5) ThisWorkbook.Sheets("Лист2").Cells(i, 53) = avArr(lr, 11) ThisWorkbook.Sheets("Лист2").Cells(i, 59) = avArr(lr, 12) i = i + 1: Exit For End If Next i Next lr
Next
If bPolyBooks Then Workbooks(oAwb).Close False Range("Q9:Q1000").Replace What:="m", Replacement:="м", LookAt:=xlWhole Range("Q9:Q1000").Replace What:="pc", Replacement:="шт", LookAt:=xlWhole Range("Q9:Q1000").Replace What:="set", Replacement:="компл", LookAt:=xlWhole For Each cell In Range("BA9:BA1000") If IsNumeric(cell.Value) And cell.Value <> "" Then ' Умножаются только ячейки, содержащие числовые данные cell.Value = cell.Value * t
End If Next
For Each cell In Range("BG9:BG1000") If IsNumeric(cell.Value) And cell.Value <> "" Then ' Умножаются только ячейки, содержащие числовые данные cell.Value = cell.Value * t
End If Next End Sub
[/vba]
У меня получился вполне работоспособный макрос, не без вашего участия сильные мира сего,конечно. Буду рад предложениям по оптимизации данного кода. Выложить могу только файл из которого собираются данные, файл В КОТОРЫЙ они собираются выложить не могу потому что в оригинале он весит 318кб, а WinRar напрочь отказывается уложить его в заявленные 100Кб. Но думаю если макрос вставить в любой, даже новый документ проблем вроде бы возникнуть не должно......
Я ведь просил - оформлять код тегами! если непонятно - кнопочка соответствующая есть, с решёточкой! Ну заодно ещё и отступы расставил, а то читать невозможно... Модератор.maloy
Workbooks(oAwb).Sheets("Attachment to Invoice").Activate
[/vba] вот это непонятно что зачем откуда... Вообще всюду, где в коде написано Range или Cells - желательно явно указывать, чьё это хозяйство. Вот как тут: [vba]
Code
ThisWorkbook.Sheets("Лист2").Cells(i, 1)
[/vba] а тут чьё? [vba]
Code
avArr = Range("C4:N2000").Value
[/vba]
[vba]
Code
Workbooks(oAwb).Sheets("Attachment to Invoice").Activate
[/vba] вот это непонятно что зачем откуда... Вообще всюду, где в коде написано Range или Cells - желательно явно указывать, чьё это хозяйство. Вот как тут: [vba]
Workbooks(oAwb).Sheets("Attachment to Invoice").Activate avArr = Range("C4:N2000").Value 'выбор диапозона значений в исходном листе For lr = 1 To UBound(avArr, 1) For i = 9 To 2000 If ThisWorkbook.Sheets("Лист2").Cells(i, 1) = "" Then ThisWorkbook.Sheets("Лист2").Cells(i, 1) = avArr(lr, 8) ThisWorkbook.Sheets("Лист2").Cells(i, 35) = avArr(lr, 4) ThisWorkbook.Sheets("Лист2").Cells(i, 17) = avArr(lr, 5) ThisWorkbook.Sheets("Лист2").Cells(i, 53) = avArr(lr, 11) ThisWorkbook.Sheets("Лист2").Cells(i, 59) = avArr(lr, 12) i = i + 1: Exit For End If Next i Next lr
[/vba]
Зачем активировать непонятный файл? Чей диапазон? Почему нужно 2000*2000 раз перебирать ячейки? (ну почти столько... ) Причём кажется переписывая данные поверх много раз - хотя без файла влом всё детально просчитывать в голове...
Не нравится вот это место:
[vba]
Code
Workbooks(oAwb).Sheets("Attachment to Invoice").Activate avArr = Range("C4:N2000").Value 'выбор диапозона значений в исходном листе For lr = 1 To UBound(avArr, 1) For i = 9 To 2000 If ThisWorkbook.Sheets("Лист2").Cells(i, 1) = "" Then ThisWorkbook.Sheets("Лист2").Cells(i, 1) = avArr(lr, 8) ThisWorkbook.Sheets("Лист2").Cells(i, 35) = avArr(lr, 4) ThisWorkbook.Sheets("Лист2").Cells(i, 17) = avArr(lr, 5) ThisWorkbook.Sheets("Лист2").Cells(i, 53) = avArr(lr, 11) ThisWorkbook.Sheets("Лист2").Cells(i, 59) = avArr(lr, 12) i = i + 1: Exit For End If Next i Next lr
[/vba]
Зачем активировать непонятный файл? Чей диапазон? Почему нужно 2000*2000 раз перебирать ячейки? (ну почти столько... ) Причём кажется переписывая данные поверх много раз - хотя без файла влом всё детально просчитывать в голове...Hugo
Обо всём по порядку. 1) Извините за то что неправильно оформил, но это мой первый опыт, а если учесть что я на форуме только сегодня зарегился, то простить мне это можно будет без труда. 2) и по существу. Обратится к конкретному файлу можно лишь в одном случае, если ты на 1000% уверен что при любых обстоятельствах ты будешь обращатся именно к нему. А так как выбор файла предоставлен пользователю, то такой гарантии ни разу никто не даст, поэтому имя файла заносится в переменную и от сюда Workbooks(oAwb).Sheets("Attachment to Invoice").Activate Вся прелесть заключается в том что только название листа в книге от куда берутся данные остаётся постоянным, сами книги носят различные имена. avArr = Range("C4:N2000").Value - Это диапазон из файла в приложении, опять же повторюсь, эти файлы бывают различны, количество наименований в них может быть от 5 до 1500( это максимально сколько я видел), но бог его знает как дальше дело пойдёт, поэтому диапазон такой большой. Вам не кажется, данные действительно постоянно надо перезаписывать, так как данный документ является шаблоном. То есть данные внесли, нажали "сохранить как". Очистили шаблон и по новой..... Надеюсь всё понятно объяснил...... Хотя сдаётся мне у меня с этим явные проблемы)))
Обо всём по порядку. 1) Извините за то что неправильно оформил, но это мой первый опыт, а если учесть что я на форуме только сегодня зарегился, то простить мне это можно будет без труда. 2) и по существу. Обратится к конкретному файлу можно лишь в одном случае, если ты на 1000% уверен что при любых обстоятельствах ты будешь обращатся именно к нему. А так как выбор файла предоставлен пользователю, то такой гарантии ни разу никто не даст, поэтому имя файла заносится в переменную и от сюда Workbooks(oAwb).Sheets("Attachment to Invoice").Activate Вся прелесть заключается в том что только название листа в книге от куда берутся данные остаётся постоянным, сами книги носят различные имена. avArr = Range("C4:N2000").Value - Это диапазон из файла в приложении, опять же повторюсь, эти файлы бывают различны, количество наименований в них может быть от 5 до 1500( это максимально сколько я видел), но бог его знает как дальше дело пойдёт, поэтому диапазон такой большой. Вам не кажется, данные действительно постоянно надо перезаписывать, так как данный документ является шаблоном. То есть данные внесли, нажали "сохранить как". Очистили шаблон и по новой..... Надеюсь всё понятно объяснил...... Хотя сдаётся мне у меня с этим явные проблемы)))maloy
1. Хорошо, впредь не забывайте - так ведь аккуратнее и читать код легче. 2. Тут Вы не правы. Тем более что файл выбирает пользователь ( в диалоге ведь выбирает) - значит известен путь к файлу, он открывается: [vba]
Code
Workbooks.Open Filename:=avFiles(li)
[/vba] Так открывайте так: [vba]
Code
Set wb = Workbooks.Open(avFiles(li)) ' открываем файл
[/vba] и затем далее например так: [vba]
Code
avArr = wb.Sheets("Attachment to Invoice").Range("C4:N2000").Value 'выбор диапазона значений в исходном листе
[/vba]
Ну в общем там у Вас есть связь avFiles(li)/oAwb/Workbooks(oAwb), но это шатко и ненадёжно... А если нужно работать с открытым ранее неизвестным файлом - всегда можно поймать момент, когда он активен, и получить ссылку [vba]
Code
Set wb = ActiveWorkbook
[/vba] По перезаписи - например у Вас i=10 в худшем случае 2000 раз (это внутренний цикл). Это значит, что возможно в ячейку Cells(10, 1) 2000 раз будет записываться значение из avArr(lr, 8). Зачем?
1. Хорошо, впредь не забывайте - так ведь аккуратнее и читать код легче. 2. Тут Вы не правы. Тем более что файл выбирает пользователь ( в диалоге ведь выбирает) - значит известен путь к файлу, он открывается: [vba]
Code
Workbooks.Open Filename:=avFiles(li)
[/vba] Так открывайте так: [vba]
Code
Set wb = Workbooks.Open(avFiles(li)) ' открываем файл
[/vba] и затем далее например так: [vba]
Code
avArr = wb.Sheets("Attachment to Invoice").Range("C4:N2000").Value 'выбор диапазона значений в исходном листе
[/vba]
Ну в общем там у Вас есть связь avFiles(li)/oAwb/Workbooks(oAwb), но это шатко и ненадёжно... А если нужно работать с открытым ранее неизвестным файлом - всегда можно поймать момент, когда он активен, и получить ссылку [vba]
Code
Set wb = ActiveWorkbook
[/vba] По перезаписи - например у Вас i=10 в худшем случае 2000 раз (это внутренний цикл). Это значит, что возможно в ячейку Cells(10, 1) 2000 раз будет записываться значение из avArr(lr, 8). Зачем?Hugo