#excel #vba
#excel #vba
Вопрос:
Я опубликовал это в mrexcel, но не получил ответа. Вот почему я публикую здесь.
У меня возникли две проблемы с приведенным ниже кодом.
- Если диапазон содержит только одну строку, например,
H12-K12
тогда он выполняется только для первой ячейкиI12
, а затем останавливается. Но он должен выполняться доK15
. - Если диапазон содержит несколько строк как
H12-K15
, то он выполняется доI15
и после этого останавливается. Но он должен выполняться доK15
.
Что я делаю не так?
Данные…..
Требуется вывод, как показано ниже. Требуемый вывод
Option Explicit
Sub CreatPackingList()
' On Error Resume Next
Dim xTitleId As String
xTitleId = "Input box--"
Dim WorkRng As Range
Set WorkRng = Application.Selection
Set WorkRng = Application.InputBox("Range", xTitleId, WorkRng.Address, Type:=8)
Dim xNum As Integer
xNum = Application.InputBox("Division num", xTitleId, Type:=1)
Dim Rng As Range
For Each Rng In WorkRng
If Rng.Value > xNum Then
Dim nThNumber As Double
nThNumber = Rng.Value / xNum
Dim nThNumberNoDecimil As Single
nThNumberNoDecimil = nThNumber
'to remove decimil data
Dim nThNumberNoDecInt As Integer
nThNumberNoDecInt = CInt(Fix(nThNumberNoDecimil))
Dim totalValue As Integer
totalValue = nThNumberNoDecInt * xNum
Dim balanceValue As Integer
balanceValue = Rng.Value - totalValue
Rng.Value = xNum
Rng.EntireRow.Copy
Dim cUrrentCellCol As Integer
cUrrentCellCol = Range(Rng.Offset(0, 0), Rng.Offset(0, 0)).Column
Dim cUrrentCellRow As Integer
cUrrentCellRow = Range(Rng.Offset(0, 0), Rng.Offset(0, 0)).Row
'coPyRowNThTime
'----------------------
If balanceValue > 0 Then
Dim coPyRowNThTime As Integer
coPyRowNThTime = 2
Range(Rng.Offset(1, 0), Rng.Offset(coPyRowNThTime, 0)).EntireRow.Insert Shift:=xlDown
Range(Rng.Offset(1, 0), Rng.Offset(1, 0)).Value = balanceValue
Range(Rng.Offset(2, 0), Rng.Offset(2, 0)).ClearContents
'Ctn no at column T
Cells(cUrrentCellRow, 20).Value = nThNumberNoDecInt
Cells(cUrrentCellRow, 20).Offset(1, 0).Value = 1
If cUrrentCellCol = 8 Then
Range(Cells(cUrrentCellRow, 9), Cells(cUrrentCellRow, 19)).ClearContents
Range(Cells(cUrrentCellRow, 9).Offset(1, 0), Cells(cUrrentCellRow, 19).Offset(1, 0)).ClearContents
ElseIf cUrrentCellCol = 19 Then
Range(Cells(cUrrentCellRow, 8), Cells(cUrrentCellRow, 18)).ClearContents
Range(Cells(cUrrentCellRow, 8).Offset(1, 0), Cells(cUrrentCellRow, 18).Offset(1, 0)).ClearContents
Else
Dim leftColNumber As Integer
leftColNumber = cUrrentCellCol - 1
Dim rightColNumber As Integer
rightColNumber = cUrrentCellCol 1
Range(Cells(cUrrentCellRow, 8), Cells(cUrrentCellRow, leftColNumber)).ClearContents
Range(Cells(cUrrentCellRow, 8).Offset(1, 0), Cells(cUrrentCellRow, leftColNumber).Offset(1, 0)).ClearContents
Range(Cells(cUrrentCellRow, rightColNumber), Cells(cUrrentCellRow, 19)).ClearContents
Range(Cells(cUrrentCellRow, rightColNumber).Offset(1, 0), Cells(cUrrentCellRow, 19).Offset(1, 0)).ClearContents
End If
'delete emptye row in H-S column, if qty is nothing
If WorksheetFunction.CountA(Range(Cells(cUrrentCellRow, 8).Offset(2, 0), Cells(cUrrentCellRow, 19).Offset(2, 0))) = 0 Then
Range(Cells(cUrrentCellRow, 8).Offset(2, 0), Cells(cUrrentCellRow, 18).Offset(2, 0)).EntireRow.Delete
End If
Else
coPyRowNThTime = 1
Range(Rng.Offset(1, 0), Rng.Offset(coPyRowNThTime, 0)).EntireRow.Insert Shift:=xlDown
Range(Rng.Offset(1, 0), Rng.Offset(1, 0)).ClearContents
'Ctn no at column T
Cells(cUrrentCellRow, 20).Value = nThNumberNoDecInt
If cUrrentCellCol = 8 Then
Range(Cells(cUrrentCellRow, 9), Cells(cUrrentCellRow, 19)).ClearContents
ElseIf cUrrentCellCol = 19 Then
Range(Cells(cUrrentCellRow, 8), Cells(cUrrentCellRow, 18)).ClearContents
Else
leftColNumber = cUrrentCellCol - 1
rightColNumber = cUrrentCellCol 1
Range(Cells(cUrrentCellRow, 8), Cells(cUrrentCellRow, leftColNumber)).ClearContents
Range(Cells(cUrrentCellRow, rightColNumber), Cells(cUrrentCellRow, 19)).ClearContents
End If
'delete emptye row in H-S column, if qty is nothing
If WorksheetFunction.CountA(Range(Cells(cUrrentCellRow, 8).Offset(1, 0), Cells(cUrrentCellRow, 19).Offset(1, 0))) = 0 Then
Range(Cells(cUrrentCellRow, 8).Offset(1, 0), Cells(cUrrentCellRow, 18).Offset(1, 0)).EntireRow.Delete
End If
End If
'---------------------
End If
Next
End Sub
Комментарии:
1. 1. Форматированный код очень полезен. 2. Какова цель
On Error Resume Next
, когда вы не улавливаете никаких ошибок и не возвращаете перехват ошибок в нормальное состояние. (Я отредактировал ваш код и удалил, поскольку для этого нет причин). 3. Ваши диапазоны не указаны. Предлагаю просмотреть ваш код и обновить. Посмотрите на RubberDuck или MZ-Tools, чтобы помочь с обновлениями.2. Основная причина, по которой ваш код «останавливается», заключается в том, что на первой итерации цикла при обработке ячейки
I12
строкаRange(Cells(cUrrentCellRow, rightColNumber), Cells(cUrrentCellRow, 19)).ClearContents
очищает ячейкиJ12:K12
. Поэтому, когда цикл For переходит к следующей итерации,Rng
будет ссылаться наJ12
иIf Rng.Value > xNum Then
будет False . Совсем не ясно, что вы пытаетесь здесь сделать, поэтому я не буду гадать о возможных исправлениях. Тем не менее, пара основ: избавьтесь отOn Error Resumre Next
и, поскольку вы вставляете строки, выполняйте цикл снизу вверх от вашего диапазона строк.3. Даже после возобновления работы с ошибкой он действует одинаково. Вот мой файл с кодом. файл
4. @MehidyHassan конечно, это действует одинаково — вы не поняли остальную часть моего комментария?
5. для редакторов: удаление
On Error Resume Next
и правильный отступ стали бы частью хорошего ответа на вопрос, а не редактирования
Ответ №1:
Я получаю требуемый результат с помощью приведенного ниже кода, переворачивает цикл снизу вверх.
Sub CreatPackingListReverse()
Dim i As Long, rng As Range, t As String
Dim xTitleId As String
xTitleId = "Input box--"
Set rng = Application.InputBox("Range", xTitleId, Type:=8)
t = rng.Address
Dim xNum As Integer
xNum = Application.InputBox("Division num", xTitleId, Type:=1)
For i = Range(t).Cells.Count To 1 Step -1
If rng.Item(i).Value > xNum Then
Dim nThNumber As Double
nThNumber = rng.Item(i).Value / xNum
Dim nThNumberNoDecimil As Single
nThNumberNoDecimil = nThNumber
'to remove decimil data
Dim nThNumberNoDecInt As Integer
nThNumberNoDecInt = CInt(Fix(nThNumberNoDecimil))
Dim totalValue As Integer
totalValue = nThNumberNoDecInt * xNum
Dim balanceValue As Integer
balanceValue = rng.Item(i).Value - totalValue
rng.Item(i).Value = xNum
rng.Item(i).EntireRow.Copy
Dim cUrrentCellCol As Integer
cUrrentCellCol = rng.Item(i).Column
Dim cUrrentCellRow As Integer
cUrrentCellRow = rng.Item(i).Row
'coPyRowNThTime
'----------------------
If balanceValue > 0 Then
Dim coPyRowNThTime As Integer
coPyRowNThTime = 2
Range(rng.Item(i).Offset(1, 0), rng.Item(i).Offset(coPyRowNThTime, 0)).EntireRow.Insert Shift:=xlDown
rng.Item(i).Offset(2, 0).Value = balanceValue
rng.Item(i).ClearContents
'Ctn no at column T
Cells(cUrrentCellRow, 20).Offset(1, 0).Value = nThNumberNoDecInt
Cells(cUrrentCellRow, 20).Offset(2, 0).Value = 1
If cUrrentCellCol = 8 Then
Range(Cells(cUrrentCellRow, 9).Offset(1, 0), Cells(cUrrentCellRow, 19).Offset(1, 0)).ClearContents
Range(Cells(cUrrentCellRow, 9).Offset(2, 0), Cells(cUrrentCellRow, 19).Offset(2, 0)).ClearContents
ElseIf cUrrentCellCol = 19 Then
Range(Cells(cUrrentCellRow, 8).Offset(1, 0), Cells(cUrrentCellRow, 18).Offset(1, 0)).ClearContents
Range(Cells(cUrrentCellRow, 8).Offset(2, 0), Cells(cUrrentCellRow, 18).Offset(2, 0)).ClearContents
Else
Dim leftColNumber As Integer
leftColNumber = cUrrentCellCol - 1
Dim rightColNumber As Integer
rightColNumber = cUrrentCellCol 1
Range(Cells(cUrrentCellRow, 8).Offset(1, 0), Cells(cUrrentCellRow, leftColNumber).Offset(1, 0)).ClearContents
Range(Cells(cUrrentCellRow, 8).Offset(2, 0), Cells(cUrrentCellRow, leftColNumber).Offset(2, 0)).ClearContents
Range(Cells(cUrrentCellRow, rightColNumber).Offset(1, 0), Cells(cUrrentCellRow, 19).Offset(1, 0)).ClearContents
Range(Cells(cUrrentCellRow, rightColNumber).Offset(2, 0), Cells(cUrrentCellRow, 19).Offset(2, 0)).ClearContents
End If
'delete emptye row in H-S column, if qty is nothing
If WorksheetFunction.CountA(Range(Cells(cUrrentCellRow, 8), Cells(cUrrentCellRow, 19))) = 0 Then
'Range(Cells(cUrrentCellRow, 8), Cells(cUrrentCellRow, 19)).EntireRow.Delete
rng.Item(i).EntireRow.Delete
End If
Else
coPyRowNThTime = 1
Range(rng.Item(i).Offset(1, 0), rng.Item(i).Offset(coPyRowNThTime, 0)).EntireRow.Insert Shift:=xlDown
rng.Item(i).ClearContents
'Ctn no at column T
Cells(cUrrentCellRow, 20).Offset(1, 0).Value = nThNumberNoDecInt
If cUrrentCellCol = 8 Then
Range(Cells(cUrrentCellRow, 9).Offset(1, 0), Cells(cUrrentCellRow, 19).Offset(1, 0)).ClearContents
ElseIf cUrrentCellCol = 19 Then
Range(Cells(cUrrentCellRow, 8).Offset(1, 0), Cells(cUrrentCellRow, 18).Offset(1, 0)).ClearContents
Else
leftColNumber = cUrrentCellCol - 1
rightColNumber = cUrrentCellCol 1
Range(Cells(cUrrentCellRow, 8).Offset(1, 0), Cells(cUrrentCellRow, leftColNumber).Offset(1, 0)).ClearContents
Range(Cells(cUrrentCellRow, rightColNumber).Offset(1, 0), Cells(cUrrentCellRow, 19).Offset(1, 0)).ClearContents
End If
'delete emptye row in H-S column, if qty is nothing
If WorksheetFunction.CountA(Range(Cells(cUrrentCellRow, 8), Cells(cUrrentCellRow, 19))) = 0 Then
'Range(Cells(cUrrentCellRow, 8), Cells(cUrrentCellRow, 19)).EntireRow.Delete
rng.Item(i).EntireRow.Delete
End If
End If
'---------------------
Else
cUrrentCellRow = rng.Item(i).Row
rng.Item(i).Value = rng.Item(i).Value
Cells(cUrrentCellRow, 20).Value = 1
End If
Next i
End Sub