Доброго времени суток! Помогите решить задачу чайнику. На листе есть таблицы (штук 30) с размерами (длина*ширина) и количеством. Сверху каждой таблицы - кол-во таких изделий. Нужно сформировать итоговую таблицу (на этом же листе) без пустых строк, с количеством деталей как в исходной, умноженной на кол-во изделий. В файле примера внизу таблица, которую нужно получить. Заранее спасибо всем, кто поможет.
Доброго времени суток! Помогите решить задачу чайнику. На листе есть таблицы (штук 30) с размерами (длина*ширина) и количеством. Сверху каждой таблицы - кол-во таких изделий. Нужно сформировать итоговую таблицу (на этом же листе) без пустых строк, с количеством деталей как в исходной, умноженной на кол-во изделий. В файле примера внизу таблица, которую нужно получить. Заранее спасибо всем, кто поможет.joker007
Sub ertert() Dim x, i&, j&, t(), s$ With CreateObject("Scripting.Dictionary") .CompareMode = 1 For i = 4 To Cells(5, Columns.Count).End(xlToLeft).Column Step 6 x = Cells(5, i).CurrentRegion.Value For j = 3 To UBound(x) s = x(j, 1) & x(j, 2) If .Exists(s) Then t = .Item(s): t(2) = t(2) + x(j, 3) .Item(s) = t() Else .Item(s) = Array(x(j, 1), x(j, 2), x(j, 3)) End If Next j Next i Range("D29").Resize(.Count, 3).Value = Application.Index(.Items, 0, 0) End With End Sub
[/vba]
joker007, привет попробуйте вот так [vba]
Код
Sub ertert() Dim x, i&, j&, t(), s$ With CreateObject("Scripting.Dictionary") .CompareMode = 1 For i = 4 To Cells(5, Columns.Count).End(xlToLeft).Column Step 6 x = Cells(5, i).CurrentRegion.Value For j = 3 To UBound(x) s = x(j, 1) & x(j, 2) If .Exists(s) Then t = .Item(s): t(2) = t(2) + x(j, 3) .Item(s) = t() Else .Item(s) = Array(x(j, 1), x(j, 2), x(j, 3)) End If Next j Next i Range("D29").Resize(.Count, 3).Value = Application.Index(.Items, 0, 0) End With End Sub
nilem, спасибо большое, работает! Только, как сделать, чтобы значения в третьей колонке (количество) получалось из количества в исходной таблице, умноженной на кол-во изделий (жёлтая ячейка).
nilem, спасибо большое, работает! Только, как сделать, чтобы значения в третьей колонке (количество) получалось из количества в исходной таблице, умноженной на кол-во изделий (жёлтая ячейка).joker007
Sub ertert() Dim x, i&, j&, t(), s$ With CreateObject("Scripting.Dictionary") .CompareMode = 1 For i = 4 To Cells(5, Columns.Count).End(xlToLeft).Column Step 6 x = Cells(5, i).CurrentRegion.Value For j = 3 To UBound(x) s = x(j, 1) & x(j, 2) If .Exists(s) Then t = .Item(s): t(2) = t(2) + x(j, 3) * x(1, 1) '*** .Item(s) = t() Else .Item(s) = Array(x(j, 1), x(j, 2), x(j, 3) * x(1, 1)) '*** End If Next j Next i Range("D29").Resize(.Count, 3).Value = Application.Index(.Items, 0, 0) End With End Sub
[/vba]
добавил в 2-х строках со звездочками [vba]
Код
Sub ertert() Dim x, i&, j&, t(), s$ With CreateObject("Scripting.Dictionary") .CompareMode = 1 For i = 4 To Cells(5, Columns.Count).End(xlToLeft).Column Step 6 x = Cells(5, i).CurrentRegion.Value For j = 3 To UBound(x) s = x(j, 1) & x(j, 2) If .Exists(s) Then t = .Item(s): t(2) = t(2) + x(j, 3) * x(1, 1) '*** .Item(s) = t() Else .Item(s) = Array(x(j, 1), x(j, 2), x(j, 3) * x(1, 1)) '*** End If Next j Next i Range("D29").Resize(.Count, 3).Value = Application.Index(.Items, 0, 0) End With End Sub
nilem, спасибо большое. В примере работает как надо. Буду пытаться "прикрутить" к реальной таблице. Пока выдаёт ошибку "13" о несоответствии типов.
nilem, спасибо большое. В примере работает как надо. Буду пытаться "прикрутить" к реальной таблице. Пока выдаёт ошибку "13" о несоответствии типов.joker007
Sub www() Dim k&, s&, t&, i& k = 4 s = 30 For t = 1 To 3 For i = 7 To Cells(7, k).End(xlDown).Row Cells(s, 4) = Cells(i, k) Cells(s, 5) = Cells(i, k + 1) Cells(s, 6) = Cells(i, k + 2) * Cells(5, k) s = s + 1 Next k = k + 5 Next End Sub
[/vba]
При неизменной расстановке таблиц можно так [vba]
Код
Sub www() Dim k&, s&, t&, i& k = 4 s = 30 For t = 1 To 3 For i = 7 To Cells(7, k).End(xlDown).Row Cells(s, 4) = Cells(i, k) Cells(s, 5) = Cells(i, k + 1) Cells(s, 6) = Cells(i, k + 2) * Cells(5, k) s = s + 1 Next k = k + 5 Next End Sub
К сожалению код nilem не хочет работать, когда вокруг таблиц есть ещё данные. Wasilic, это почти то, что нужно. Как бы сделать так, чтобы макрос не останавливался, если какая-то таблица оказалась пустой, а проходил по всем. Просто сформировать нужно три сводных таблицы: по голубым, салатовым и розовым полям. И не все из них будут заполнены.
К сожалению код nilem не хочет работать, когда вокруг таблиц есть ещё данные. Wasilic, это почти то, что нужно. Как бы сделать так, чтобы макрос не останавливался, если какая-то таблица оказалась пустой, а проходил по всем. Просто сформировать нужно три сводных таблицы: по голубым, салатовым и розовым полям. И не все из них будут заполнены.joker007
Sub example_01() Dim rng As Range, x, i&, j& Dim aMDF As Object, aDVP As Object, aDSP As Object Set rng = Range("D5:F29") Set aMDF = CreateObject("System.Collections.ArrayList") Set aDVP = CreateObject("System.Collections.ArrayList") Set aDSP = CreateObject("System.Collections.ArrayList")
For j = 0 To 146 Step 5 x = rng.Offset(, j).Value For i = 3 To 17 If x(i, 3) > 0 Then aMDF.Add Array(x(i, 1), x(i, 2), x(i, 3) * x(1, 1)) Next For i = 19 To 21 If x(i, 3) > 0 Then aDVP.Add Array(x(i, 1), x(i, 2), x(i, 3) * x(1, 1)) Next For i = 23 To 25 If x(i, 3) > 0 Then aDSP.Add Array(x(i, 1), x(i, 2), x(i, 3) * x(1, 1)) Next Next j Range("D90").Resize(, 11).CurrentRegion.ClearContents With aMDF If .Count > 0 Then Range("D90").Resize(.Count, 3).Value = Application.Index(.ToArray, 0, 0) End With With aDVP If .Count > 0 Then Range("H90").Resize(.Count, 3).Value = Application.Index(.ToArray, 0, 0) End With With aDSP If .Count > 0 Then Range("L90").Resize(.Count, 3).Value = Application.Index(.ToArray, 0, 0) End With Set aMDF = Nothing: Set aDVP = Nothing: Set aDSP = Nothing End Sub
[/vba] или без объектов :(
[vba]
Код
Sub example_02() Dim rng As Range, x, i&, j&, rez(), rw&() Set rng = Range("D5:F29") ReDim rez(1 To 450, 1 To 11): ReDim rw(1 To 3)
For j = 0 To 146 Step 5 x = rng.Offset(, j).Value For i = 3 To 17 If x(i, 3) > 0 Then rw(1) = rw(1) + 1: rez(rw(1), 1) = x(i, 1): rez(rw(1), 2) = x(i, 2): rez(rw(1), 3) = x(i, 3) * x(1, 1) Next For i = 19 To 21 If x(i, 3) > 0 Then rw(2) = rw(2) + 1: rez(rw(2), 5) = x(i, 1): rez(rw(2), 6) = x(i, 2): rez(rw(2), 7) = x(i, 3) * x(1, 1) Next For i = 23 To 25 If x(i, 3) > 0 Then rw(3) = rw(3) + 1: rez(rw(3), 9) = x(i, 1): rez(rw(3), 10) = x(i, 2): rez(rw(3), 11) = x(i, 3) * x(1, 1) Next Next j Range("D90").Resize(UBound(rez, 1), UBound(rez, 2)).Value = rez() End Sub
[/vba]
а если так :) [vba]
Код
Sub example_01() Dim rng As Range, x, i&, j& Dim aMDF As Object, aDVP As Object, aDSP As Object Set rng = Range("D5:F29") Set aMDF = CreateObject("System.Collections.ArrayList") Set aDVP = CreateObject("System.Collections.ArrayList") Set aDSP = CreateObject("System.Collections.ArrayList")
For j = 0 To 146 Step 5 x = rng.Offset(, j).Value For i = 3 To 17 If x(i, 3) > 0 Then aMDF.Add Array(x(i, 1), x(i, 2), x(i, 3) * x(1, 1)) Next For i = 19 To 21 If x(i, 3) > 0 Then aDVP.Add Array(x(i, 1), x(i, 2), x(i, 3) * x(1, 1)) Next For i = 23 To 25 If x(i, 3) > 0 Then aDSP.Add Array(x(i, 1), x(i, 2), x(i, 3) * x(1, 1)) Next Next j Range("D90").Resize(, 11).CurrentRegion.ClearContents With aMDF If .Count > 0 Then Range("D90").Resize(.Count, 3).Value = Application.Index(.ToArray, 0, 0) End With With aDVP If .Count > 0 Then Range("H90").Resize(.Count, 3).Value = Application.Index(.ToArray, 0, 0) End With With aDSP If .Count > 0 Then Range("L90").Resize(.Count, 3).Value = Application.Index(.ToArray, 0, 0) End With Set aMDF = Nothing: Set aDVP = Nothing: Set aDSP = Nothing End Sub
[/vba] или без объектов :(
[vba]
Код
Sub example_02() Dim rng As Range, x, i&, j&, rez(), rw&() Set rng = Range("D5:F29") ReDim rez(1 To 450, 1 To 11): ReDim rw(1 To 3)
For j = 0 To 146 Step 5 x = rng.Offset(, j).Value For i = 3 To 17 If x(i, 3) > 0 Then rw(1) = rw(1) + 1: rez(rw(1), 1) = x(i, 1): rez(rw(1), 2) = x(i, 2): rez(rw(1), 3) = x(i, 3) * x(1, 1) Next For i = 19 To 21 If x(i, 3) > 0 Then rw(2) = rw(2) + 1: rez(rw(2), 5) = x(i, 1): rez(rw(2), 6) = x(i, 2): rez(rw(2), 7) = x(i, 3) * x(1, 1) Next For i = 23 To 25 If x(i, 3) > 0 Then rw(3) = rw(3) + 1: rez(rw(3), 9) = x(i, 1): rez(rw(3), 10) = x(i, 2): rez(rw(3), 11) = x(i, 3) * x(1, 1) Next Next j Range("D90").Resize(UBound(rez, 1), UBound(rez, 2)).Value = rez() End Sub
Удивлюсь, если в моем паровозе будет что то не понятно. Рабочий пример макроса для общего развития понимания стратегии.
[vba]
Код
Sub www() Dim k&, s&, i& Range("D90:G200").ClearContents s = 90 For k = 4 To 152 Step 5 For i = 7 To 21 If Cells(i, k) = 0 Then Exit For Cells(s, 4) = Cells(i, k) Cells(s, 5) = Cells(i, k + 1) Cells(s, 6) = Cells(i, k + 2) * Cells(5, k) s = s + 1 Next Next Cells(s, 5) = "ДВП" s = s + 1 For k = 4 To 152 Step 5 For i = 23 To 25 If Cells(i, k) <> 0 Then Cells(s, 4) = Cells(i, k) Cells(s, 5) = Cells(i, k + 1) Cells(s, 6) = Cells(i, k + 2) * Cells(5, k) s = s + 1 End If Next Next Cells(s, 5) = "ДСП2" s = s + 1 For k = 4 To 152 Step 5 For i = 27 To 29 If Cells(i, k) <> 0 Then Cells(s, 4) = Cells(i, k) Cells(s, 5) = Cells(i, k + 1) Cells(s, 6) = Cells(i, k + 2) * Cells(5, k) s = s + 1 End If Next Next Range("D90").Activate End Sub
Удивлюсь, если в моем паровозе будет что то не понятно. Рабочий пример макроса для общего развития понимания стратегии.
[vba]
Код
Sub www() Dim k&, s&, i& Range("D90:G200").ClearContents s = 90 For k = 4 To 152 Step 5 For i = 7 To 21 If Cells(i, k) = 0 Then Exit For Cells(s, 4) = Cells(i, k) Cells(s, 5) = Cells(i, k + 1) Cells(s, 6) = Cells(i, k + 2) * Cells(5, k) s = s + 1 Next Next Cells(s, 5) = "ДВП" s = s + 1 For k = 4 To 152 Step 5 For i = 23 To 25 If Cells(i, k) <> 0 Then Cells(s, 4) = Cells(i, k) Cells(s, 5) = Cells(i, k + 1) Cells(s, 6) = Cells(i, k + 2) * Cells(5, k) s = s + 1 End If Next Next Cells(s, 5) = "ДСП2" s = s + 1 For k = 4 To 152 Step 5 For i = 27 To 29 If Cells(i, k) <> 0 Then Cells(s, 4) = Cells(i, k) Cells(s, 5) = Cells(i, k + 1) Cells(s, 6) = Cells(i, k + 2) * Cells(5, k) s = s + 1 End If Next Next Range("D90").Activate End Sub