I am using a form that takes an item and quantity. I'm trying to create a running count that consists of the quantity (denoted as qtytxt1, qtytxt2, etc) of each item. Each item has its own quantity input field denoted with the ending number (i.e., qtytxt1 applies to item 1).
I am trying to have a cell located in (emptyRow, 27) to output the sum of the total quantity of all items inputted into the form (i.e., Item 1 qty = 2,000; Item 2 qty = 3,000; Expected Output = 5,000).
There are a total of 10 input fields for "Item/Qty," however, not all 10 fields are expected to be used. I have created a code that seems to work as I prefer, however, I would receive a sum error message when entering less than 10 items.
Dim emptyRow As Long
Dim data As Worksheet
Dim runCount As Long
Worksheets("mining history").Activate
emptyRow = WorksheetFunction.CountA(Range("i:i")) + 6
Set data = Sheets("data")
runCount = 0
If qtytxt2.Value = "" Then
qtytxt2.Value = 0
ElseIf qtytxt3.Value = "" Then
qtytxt3.Value = 0
ElseIf qtytxt4.Value = "" Then
qtytxt4.Value = 0
ElseIf qtytxt5.Value = "" Then
qtytxt5.Value = 0
ElseIf qtytxt6.Value = "" Then
qtytxt6.Value = 0
ElseIf qtytxt7.Value = "" Then
qtytxt7.Value = 0
ElseIf qtytxt8.Value = "" Then
qtytxt8.Value = 0
ElseIf qtytxt9.Value = "" Then
qtytxt9.Value = 0
ElseIf qtytxt10.Value = "" Then
qtytxt10.Value = 0
End If
If IsEmpty(Range("E:E")) Then
'Is Empty
runCount = 0
Else
' Not Empty
runCount = WorksheetFunction.Sum(qtytxt1.Value, qtytxt2.Value, qtytxt3.Value, qtytxt4.Value, qtytxt5.Value, qtytxt6.Value, qtytxt7.Value, qtytxt8.Value)
Cells(emptyRow, 27).Value = runCount
End If
You can use a loop:
Dim emptyRow As Long
Dim data As Worksheet, wsMH As Worksheet
Dim runCount As Long, n As Long, v
Set data = Sheets("data")
Set wsMH = Worksheets("mining history")
'no need to Activate...
emptyRow = wsMH.Cells(Rows.count, "I").End(xlUp).row + 1
If Application.CountA(wsMH.Range("E:E")) = 0 Then
runCount = 0
Else
'loop all the entry textboxes
For n = 1 To 10
v = Me.Controls("qtytxt" & n).Value
If Len(v) > 0 And IsNumeric(v) Then runCount = runCount + v
Next n
wsMH.Cells(emptyRow, 27).Value = runCount
End If
I suspect you need this:
If qtytxt2.Value = "" Then
qtytxt2.Value = 0
End If
If qtytxt3.Value = "" Then
qtytxt3.Value = 0
End If
etc
Related
I'm trying to clean up raw data exported from an online database.
There can be up to five columns. If all cells in a row have a value of 0, I want to delete that row.
When the user exports the data, they can choose to exclude columns, and the columns can be in any order.
For example, if the data contains only two of the possible five columns, I want to check just those two for 0s.
Could do a a big loop looking at every row and seeing if all 5 columns in that row are blank
Sub test()
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("sheetname")
Dim LastRow As Integer
LastRow = sh.UsedRange.Rows.Count - 1
For i = 1 To LastRow
If (sh.Cells(i, 1).Value = "" And sh.Cells(i, 2).Value = "" And sh.Cells(i, 3).Value = "" And _
sh.Cells(i, 4).Value = "" And sh.Cells(i, 5).Value = "") Then
sh.Cells(i, 1).EntireRow.Delete
i = i - 1
Dim newLastRow As Integer
newLastRow = sh.UsedRange.Rows.Count - 1
If i = newLastRow Then
Exit For
End If
End If
Next i
MsgBox ("Done")
End Sub
#kyle campbell, thank you for your input! It didn't quite get me there, but it did get my wheels turning. Here is the solution I came up with, if anyone's curious:
I set a variable to represent the column number for each of the 5 possible columns using Range.Find. If the Find came up with nothing, I set the variable to 49, since the maximum number of columns this report can have is 48.
Then I did a nested If to test if the value in each cell was either 0 or null (because if the column number is 49, there won't be any data there). If all Ifs were true, I deleted the row. I also added a counter and message box, just to make sure this worked.
Sub DeleteRows()
Dim O As Long
Dim E As Long
Dim H As Long
Dim B As Long
Dim P As Long
lRow = Range("A1").CurrentRegion.Rows.Count
If Range("1:1").Find("SUM(OBLIGATIONS)") Is Nothing Then
O = 49
Else
O = Range("1:1").Find("SUM(OBLIGATIONS)").Column
End If
If Range("1:1").Find("SUM(EXPENDITURES)") Is Nothing Then
E = 49
Else
E = Range("1:1").Find("SUM(EXPENDITURES)").Column
End If
If Range("1:1").Find("SUM(HOURS)") Is Nothing Then
H = 49
Else
H = Range("1:1").Find("SUM(HOURS)").Column
End If
If Range("1:1").Find("SUM(BUDGET_RESOURCES)") Is Nothing Then
B = 49
Else
B = Range("1:1").Find("SUM(BUDGET_RESOURCES)").Column
End If
If Range("1:1").Find("SUM(PRIOR_YEAR_RECOVERY)") Is Nothing Then
P = 49
Else
P = Range("1:1").Find("SUM(PRIOR_YEAR_RECOVERY)").Column
End If
Dim j As Integer
j = 0
For i = lRow To 2 Step -1
If Cells(i, O) = 0 Or Cells(i, O) = "" Then
If Cells(i, E) = 0 Or Cells(i, E) = "" Then
If Cells(i, H) = 0 Or Cells(i, H) = "" Then
If Cells(i, B) = 0 Or Cells(i, B) = "" Then
If Cells(i, P) = 0 Or Cells(i, P) = "" Then
Rows(i).Delete
j = j + 1
End If
End If
End If
End If
End If
Next i
MsgBox "Macro complete, " & j & " lines deleted."
End Sub
I have challenges in highlighting/copying alternate rows in one column and pasting it to the next column and aligned.
Here's a screenshot:
Following code assumes you have two separate tabs, SRC and DST and the range of data starts in the first cell. Will do all in a single step:
Public Sub CopyAlternate()
Dim i As Long
i = 2
While Len(Sheets("SRC").Cells(i, 1).Value) > 0
Sheets("DST").Cells(i / 2 + 1, 1).Value = Sheets("SRC").Cells(i, 1).Value
Sheets("DST").Cells(i / 2 + 1, 2).Value = Sheets("SRC").Cells(i + 1, 1).Value
i = i + 2
Wend
End Sub
You can take this code and adjust it to taste:
Sub alternate()
Dim i As Integer
Dim j As Integer
Dim n As Integer
i = 0
j = 0
n = 0
With ActiveSheet
For Each c In .Range("A4:A16")
.Cells(20 + j, 1 + i).Value = c.Value
If n = 0 Or n Mod 2 = 0 Then
i = 1
j = j
Else
i = 0
j = j + 1
End If
n = n + 1
Next c
End With
End Sub
This worked for me when rebuilding your example with letters (for faster checking).
I have created an Excel spreadsheet that extracts live data from a query in SAP GUI and paste that info back into Excel
From there, I'm opening transaction ME38 to update schedule lines based off the extracted data. I need to go to the "scheduled.." column (which I know to be "txtEKET-MENGE") and change the number shown to the "Qty Delivered" (which is a part of the extraction); however, I need to only do this on certain cells in the "Schedule..." column ("txtEKET-ETENR") [data listed on extraction as well].
When it gets to "Set grid..." it ends the function and does nothing else.
Any insight would be greatly appreciated.
Here is what I've done so far.
Set xclapp = CreateObject("Excel.Application")
Set xclwbk = ThisWorkbook
Set xclsht = xclwbk.Sheets("Sheet1")
For k = 2 To ActiveCell.SpecialCells(11).Row
For j = 1 To ActiveCell.SpecialCells(11).Column
If j = 14 Then Purch = xclsht.Cells(k, j).Value
If j = 15 Then Item = xclsht.Cells(k, j).Value
If j = 16 Then SLine = xclsht.Cells(k, j).Value
If j = 8 Then PGI = xclsht.Cells(k, j).Value
Next
myTransaction = "ME38"
Session.FindById("wnd[0]/tbar[0]/okcd").Text = "/n" & myTransaction
Session.FindById("wnd[0]").sendVKey 0
On Error Resume Next
Session.FindById("wnd[0]/usr/ctxtRM06E-EVRTN").Text = Purch
Session.FindById("wnd[0]/usr/ctxtRM06E-EVRTN").caretPosition = 10
Session.FindById("wnd[0]").sendVKey 0
Session.FindById("wnd[0]/usr/txtRM06E-EBELP").Text = Item
Session.FindById("wnd[0]/usr/txtRM06E-EBELP").caretPosition = 3
Session.FindById("wnd[0]").sendVKey 0
Session.FindById("wnd[0]/tbar[1]/btn[30]").press
Session.FindById("wnd[0]/tbar[1]/btn[2]").press
Call SelectRowOnGrid
Session.FindById("wnd[0]/mbar/menu[0]/menu[0]").Select
Session.FindById("wnd[0]").Close
On Error Resume Next
Session.FindById("wnd[1]/usr/btnSPOP-OPTION1").press
Next
End If
If Err.Number <> 0 Then
'The Excel worksheet has e.g. 3 columns of data and an error column.
xclsht.Cells(j, 21).Value = "Here is an error."
Else
xclsht.Cells(j, 21).Value = "O.K."
End If
On Error GoTo 0
The following is the Function SelectRowOnGrid.
Function SelectRowOnGrid()
Dim grid As SAPFEWSELib.GuiTableControl
Dim columnname As SAPFEWSELib.GuiTableColumn
Dim texttofind As String
Set grid = Session.FindById("wnd[0]/usr/tblSAPMM06ETC_1117/")
Set columnname = Session.FindById("wnd[0]/usr/tblSAPMM06ETC_1117/txtEKET- ETENR")
texttofind = xclsht.Cells(k, 16).Value
For k = 0 To grid.RowCount - 1
If grid.GetCellValue(k, columnname) = texttofind Then
grid.SetCurrentCell
grid.DoubleClickCurrentCell
End If
Next k
End Function
I will give you an example of how to deal with a table in SAP. In your case you use the commands for a GRID and this is not correct.
for example:
myFile = "z:\tmp\test.xlsx"
mySheet = "Test"
Set xclApp = CreateObject("Excel.Application")
Set xclwbk = xclapp.Workbooks.Open(myFile)
set xclsht = xclwbk.Sheets(mySheet)
xclApp.Visible = True
xclapp.DisplayAlerts = false
k = 1
do
set myTable = session.findById("wnd[0]/usr/ssubITEMS:SAPLFSKB:0100/tblSAPLFSKBTABLE")
if k = 1 then
'rows = myTable.RowCount
cols = myTable.Columns.Count
vRows = myTable.VisibleRowCount
for j = 0 to cols - 1
xclsht.Cells(k,j + 1).Value = myTable.columns.elementAt(j).title
next
k = k + 1
end if
for i = 0 to vRows - 1
l = 1
for j = 0 to Cols - 1
on error resume next
myVariable = trim(myTable.GetCell(i,j).Text)
if err.number <> 0 then exit for
on error goto 0
if left(right(myVariable,3),1) = "," then
myVariable = replace(myVariable, "." , "")
myVariable = replace(myVariable, "," , "")
xclsht.Cells(k,l).Value = myVariable/100
else
xclsht.Cells(k,l).Value = myVariable
end if
l = l + 1
next
if err.number <> 0 then exit for
k = k + 1
next
if err.number <> 0 then exit do
myTable.VerticalScrollbar.Position = myTable.VerticalScrollbar.Position + vRows
Loop
xclapp.ActiveWorkbook.Save
Set xclwbk = Nothing
Set xclsheet = Nothing
set xclapp = Nothing
Regards,
ScriptMan
Having a flowchart in Excel, Need to Automatically align it beautifully like we can do in Visio. Is there any code available for doing this in Excel?
Thanks.
I have written a vba code, But it is not giving beautiful result as in Visio
Sub auto_align()
On Error Resume Next
'Compile the diagram
Call Compiler
'Clear array values
For i = 0 To 99
numberofchildnodes(i) = 0
numberofnodesineachrow(i) = 0
listofnodes(i) = ""
nodeindexarray(i) = 0
parentnodearray(i) = 0
rownumberarray(i) = 0
columnnumberarray(i) = 0
numberofnodesineachrowarray(i) = 0
Next
'Get amount of space that must be given in the diagram between each nodes
rowspac = InputBox("Enter the space between rows, usually 100", "Test Modelling Tool")
colspac = InputBox("Enter the space between adjacent nodes, usually 200", "Test Modelling Tool")
'Find the listof nodes
i = 2
Do While Sheet6.Cells(1, i) <> ""
listofnodes(i - 2) = Sheet6.Cells(1, i)
i = i + 1
Loop
'Find the number of nodes
noofnodes = i - 2
orignoofnodes = noofnodes
'Find the begining node
For i = 2 To noofnodes + 1
b = False
E = False
j = 2
Do While Sheet6.Cells(j, 1) <> ""
If Sheet6.Cells(j, i) = "B" Then
b = True
End If
If Sheet6.Cells(j, i) = "E" Then
E = True
End If
j = j + 1
Loop
If b = True And E = False Then
strt_node = Sheet6.Cells(1, i)
Exit For
End If
Next
'Initialize values for start node
For i = 0 To noofnodes - 1
If listofnodes(i) = strt_node Then
Exit For
End If
Next
parentnodearray(i) = 0
nodeindexarray(i) = 1
rownumberarray(i) = 1
columnnumberarray(i) = 1
nodeindex = 1
'Call row order algorithm
'Initialize row number and column number
r = 1
cc = 1
dumnod = 1
'Loop until all the nodes has row number updated
Do
'Traverse through all the nodes
For i = 0 To noofnodes - 1
'If row number matches the exiting row number, update the row number for childs
If rownumberarray(i) = r Then
Call roworderalg(listofnodes(i))
End If
Next
'Increment the row
r = r + 1
'reinitialize column number
cc = 1
'Check if row number updated for all the nodes
rowupdatedforallnodes = True
For i = 0 To noofnodes - 1
If rownumberarray(i) = 0 Then
rowupdatedforallnodes = False
End If
Next
'Sort all the array inorder to maintain the order of calling the nodes in each row
Call BubbleSort
Loop While rowupdatedforallnodes = False
'Find the number of rows
r = rownumberarray(0)
For i = 0 To noofnodes - 1
If rownumberarray(i) > r Then
r = rownumberarray(i)
End If
Next
'From last row minus 1 row to 1st row
i = r - 1
Do
For j = 0 To noofnodes - 1
'if a node falls in given row number
If rownumberarray(j) = i Then
'update the column number as sum of child nodes column number divided by number of child nodes
columnnumberarray(j) = findcolumnnumberofparent(j)
End If
Next
i = i - 1
Loop While i <> 0
i = 2
Do While Sheet6.Cells(1, i) <> ""
'Move all the nodes in the diagram according to row and column position which is obtained by multiplying the space factor obtained from the user
x = findnumberofnode(Sheet6.Cells(1, i))
Sheet1.Shapes(Sheet6.Cells(1, i)).Top = rownumberarray(x) * rowspac
Sheet1.Shapes(Sheet6.Cells(1, i)).Left = columnnumberarray(x) * colspac
i = i + 1
Loop
'Reroute all the connectors to ensure there is no intersection between connectors
i = 2
Do While Sheet6.Cells(i, 1) <> ""
Sheet1.Shapes(Sheet6.Cells(i, 1)).RerouteConnections
i = i + 1
Loop
Sheet1.Activate
End Sub
Im a vba noobie, please help. I have 3000 rows and 40 columns.
Starting from row 5 to last row, and only look at columns 8,11,14,17,20,23,26,29,32.
I need to write a code saying that if each cells in colummns 8,11,14,17,20,23,26,29,32 and are in same row are absolutely smaller and equal to 5, then make a comment at the cell (row,40)="OK IN PROGRESS"
If one of the cell(columns 8,11,14,17,20,23,26,29,32) in each same row is absolutely bigger and equal to 5, then at the cell(row,40)=(whichever columns that is bigger than 5)&"NOT IN PROGRESS"
Also I need to rename each column's number.
8=george
11=cindy
14=jennifer
17=lucas
20=apple
23=jeff
26=may
29=kevin
32=oscar
So for instance, at the cell (row,40), if its 8 NOT IN PROGRESS, the 8 will be replaced by george.
and then next row
Here is a quick VBA solution, if that's what you need:
Sub ProcessRows()
Dim rSt As Integer, rEn As Integer, val As Integer, r As Integer
Dim cSt As Integer, cEn As Integer, c As Integer
Dim name As String, inProgressMsg As String, notInProgressMsg1 As String, notInProgressMsg2 As String
rSt = 5
rEn = 3004
val = 5
cSt = 8
cEn = 32
inProgressMsg = "OK IN PROGRESS"
notInProgressMsg2 = "NOT IN PROGRESS"
For r = rSt To rEn
notInProgressMsg1 = ""
For c = cSt To cEn Step 3
If Cells(r, c).Value > val Then
name = ReplaceNumberWithName(c)
notInProgressMsg1 = notInProgressMsg1 & name & " "
End If
Next c
If notInProgressMsg1 = "" Then
Cells(r, 40).Value = inProgressMsg
Else
Cells(r, 40).Value = notInProgressMsg1 & notInProgressMsg2
End If
Next r
End Sub
Function ReplaceNumberWithName(n As Integer) As String
ReplaceNumberWithName = "NO_NAME_FOUND"
If n = 8 Then
ReplaceNumberWithName = "george"
ElseIf n = 11 Then
ReplaceNumberWithName = "cindy"
ElseIf n = 14 Then
ReplaceNumberWithName = "jennifer"
ElseIf n = 17 Then
ReplaceNumberWithName = "lucas"
ElseIf n = 20 Then
ReplaceNumberWithName = "apple"
ElseIf n = 23 Then
ReplaceNumberWithName = "jeff"
ElseIf n = 26 Then
ReplaceNumberWithName = "may"
ElseIf n = 29 Then
ReplaceNumberWithName = "kevin"
ElseIf n = 32 Then
ReplaceNumberWithName = "oscar"
End If
End Function