Use Applescript to duplicate row n times in Apple Numbers - duplicates

After several attempts with VBA and Excel for Mac returning a syntax error, I've resorted to Applescript and Numbers. I need to print barcodes for every item in our inventory; however, the barcode printing software only recognizes printing rows and doesn't factor in the inventory cell value. I'm trying to duplicate the row n times, where n = value in column F. Additionally, the source data only includes data for columns A & B for the first variant of that product, which I need to duplicate to the additional rows as well. Please see screenshots below and let me know if you can help. Thank you!
Source data format:
Desired output:

The script will vary depending on the version of the application.
Here is the script for Numbers Version 3.x, try this :
tell application "Numbers"
tell table 1 of sheet 1 of document 1
set rc to (row count) - 1
set i to 2 -- start at the second row
set {cA, cB} to {"", ""}
repeat rc times
set tValues to value of cells of row i -- get values of this row
set n_rows to item 6 of tValues -- get value in column F
if item 1 of tValues is not missing value then -- not an empty cell
set {cA, cB} to items 1 thru 2 of tValues -- get values of cell A et B
else
set item 1 of tValues to cA -- put the Title into the empty cell (A) --> new row
set item 2 of tValues to cB -- put the Vendor into the empty cell (B) --> new row
set value of cell 1 of row i to cA -- put the Title into the empty cell (A) --> original row
set value of cell 2 of row i to cB -- put the Vendor into the empty cell (B) --> original row
end if
if n_rows > 1 then
set tc to count tValues
set x to properties of row i
if background color of x is missing value then set background color of x to {0, 0, 0}
repeat (n_rows - 1) times -- add rows
set r to make new row at after row i with properties x
repeat with j from 1 to tc -- insert values
set value of cell j of r to item j of tValues
end repeat
end repeat
set i to i + n_rows -- next row, but skip these new rows
else
set i to i + 1 -- next row
end if
end repeat
end tell
end tell
--
Here is the script for Numbers Version 2.x, try this :
tell application "Numbers"
tell table 1 of sheet 1 of document 1
set rc to (row count) - 1
set i to 2 -- start at the second row
set {cA, cB} to {"", ""}
repeat rc times
set tValues to value of cells of row i -- get values of this row
set n_rows to item 6 of tValues -- get value in column F
if item 1 of tValues is not 0.0 then -- 0.0 equal an empty cell for cells whose format is text
set {cA, cB} to items 1 thru 2 of tValues -- get values of cell A et B
else
set item 1 of tValues to cA -- put the Title into the empty cell (A) --> new row
set item 2 of tValues to cB -- put the Vendor into the empty cell (B) --> new row
set value of cell 1 of row i to cA -- put the Title into the empty cell (A) --> original row
set value of cell 2 of row i to cB -- put the Vendor into the empty cell (B) --> original row
end if
if n_rows > 1 then
set tc to count tValues
set {aa, bg, fs, va, ht, tco, fn, tw} to {alignment, background color, font size, vertical alignment, height, text color, font name, text wrap} of row i
try
bg
on error
set bg to missing value
end try
repeat (n_rows - 1) times -- add rows
add row below row i
set properties of row (i + 1) to {alignment:aa, background color:bg, font size:fs, vertical alignment:va, height:ht, text color:tco, font name:fn, text wrap:tw}
repeat with j from 1 to tc -- insert values
set value of cell j of row (i + 1) to item j of tValues
end repeat
end repeat
set i to i + n_rows -- next row, but skip these new rows
else
set i to i + 1 -- next row
end if
end repeat
end tell
end tell

Related

append row to a specific column?

function dailyprofit() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Matt");
var profit = SpreadsheetApp.getActiveSheet().getRange('O2').getValue();
sheet.appendRow([,,,profit ]);
}
Hello, i'm attempting to use appendrow to put my variable into the last blank cell of row D, however appendRow does the entre row rather than just column D.
i would like the "profit" to be appended to row 362 rather than row 363 -> see example here
Thanks!
You can use this sample code to get the last row of Column D:
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Matt");
var profit = SpreadsheetApp.getActiveSheet().getRange('O2').getValue();
var colValues = sheet.getRange("D1:D").getValues();
var count = colValues.filter(String).length
sheet.getRange(count+1,4).setValue(profit);
What it does?
Get all the column D values using sheet.getRange("D1:D").getValues()
Filter the array with string values and get its length/count. Empty cells will not be counted.
Increment the column D count by 1 and use Sheet.getRange(row,column) to get the cell below the non-empty cell in Column D. Use Range.setValue(value) to set the cell value.
Sample Output:
NOTE:
This will only work assuming you don't have an empty row in Column D.
If you have empty rows in your Column D, you might need to add few more offsets when incrementing the count.
Example:
I have 2 empty header rows (rows 1 and 2). Therefore, the offset of row count should be +3.
Sample Code:
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Matt");
var profit = SpreadsheetApp.getActiveSheet().getRange('O2').getValue();
var colValues = sheet.getRange("D1:D").getValues();
var count = colValues.filter(String).length
sheet.getRange(count+3,4).setValue(profit);

excel vba - add table column with date based on adjacent cell that includes date and time

I have an excel table ("Table1") with 4 total columns. The 3rd and 4th column contain 'clock in' and 'clock out' information formatted to show date and time. For example :
6/3/2016 10:54:52 AM
I would like to do two things here...first, I want to create a new, 3rd column that just reads the date, formatted "d-mmm". This should match the date found in what would now be column 4.
The second thing I would like to do is take the date portion of text out of what would now be columns 4 and 5. So at the end, an example row of data might read as follows (columns 3:5):
C, D, E
7-Jun, 10:54:52 AM, 4:59:44 AM
Here is what I have so far for code:
Sub test()
Dim currentSht As Worksheet
Dim lst As ListObject
Set curretnSht = ActiveWorkbook.Sheets(1)
Set lst = currentSht.ListObjects("Table1")
lst.ListColumns.Add Position:=3
'Not really sure how to do the rest
End Sub
That's not the Excel way. Dates are numbers 0 represents 1/1/1900. Add 1 to it and you get the next day the value of an hour is 1/24 .
The biggest problem of your approach is Excel you stop editing the cell Excel evaluate the cells value. It'll still look like 7 - Jun but Excel changes the cells format and the cells value to be 7 - Jun of this your 6/7/216. It's best to have all the cells equal the same date. Just change the cells formatting to display the results that you want. If you need to calculate the Month use the a WorkSheet Function to do so. =Month(A1)
Try this:
Sub Demo()
Range("C1").EntireColumn.Insert '-->insert column
Range("D:D").Copy Destination:=Range("C1") '-->copy column 4 to column 3
Range("C:C").NumberFormat = "d-mmm" '-->format column 3
Range("D:E").NumberFormat = "h:mm:ss AM/PM" '-->format column 4 and 5
End Sub
Even this will work:
Sub Demo()
Dim currentSht As Worksheet
Dim lastRow As Long
Set currentSht = ActiveWorkbook.Sheets("Sheet1")
lastRow = currentSht.Cells(Rows.Count, "C").End(xlUp).Row '-->get last row with data
currentSht.Range("C1").EntireColumn.Insert '-->insert column
currentSht.Range("C1:C" & lastRow) = currentSht.Range("D1:D" & lastRow).Value '-->copy column 4 to column 3
currentSht.Range("C1:C" & lastRow).NumberFormat = "d-mmm" '-->format column 3
currentSht.Range("D1:E" & lastRow).NumberFormat = "h:mm:ss AM/PM" '-->format column 4 and 5
End Sub
This meets your specs:
Sub InsertColumnAndFormatDates()
Columns("C:C").Copy
Selection.Insert Shift:=xlToRight
Application.CutCopyMode = False
Columns("C").NumberFormat = "d-mmm"
Columns("D:E").NumberFormat = "h:mm:ss AM/PM"
End Sub

Is there an excel function to duplicate rows based on a range of numbers in a cell?

I am trying to do an import into a database and each product variation has to be line by line. Unfortunately the person who set this up, one of the cells has a range of say for example 1-50. I was wondering if there was some way to duplicate the rows with the exact information, except replacing the cell with 1, then a new row with 2, etc all the way to 50.
I don't know if there is a function to do that but, you can use excel macros to solve your problem.
I tried with a simple example:
Assume your excel file format is
Name Range
A 3
B 5
After you run VBA script it becomes
Name Range
A 1
A 2
A 3
B 1
B 2
B 3
B 4
B 5
I changed the code with "bottom to top" version because it's a better solution
Private Sub InsertBottomToTop()
Dim i, cursor As Integer
cursor = 5 '# of rows you have initially (including header)'
For cursor = 5 To 2 Step -1
For i = 0 To Cells(cursor, 2) - 2
Cells(cursor, 1).EntireRow.Copy
Range("A" & Cells(cursor, 1).Row + 1).Insert Shift:=xlDown
Application.CutCopyMode = False
Cells(cursor, 2).Value = Cells(cursor, 2).Value - 1
Next i
Next cursor
End Sub

How to display the maximum value from one column in a listbox, in a textbox on the same form

How can I select the maximum value from a column in a listbox, and display that value in a textbox on the same form? The listbox itself is populated by a query that depends on user inputs, so its values are unknown in advance.
I could sort the listbox by value and select the first value, but it is already sorted by date on another column, for a different purpose. What I want to know is the Date on which that maximimum value occurred in column 2.
The next step is to display or all the values in column 4 which occure before that date as blank or N/A.
You may find the following VBA code helpful. It scans values inside the .Column data for a list box named List0, for example...
2013-04-18 | 123
2013-04-17 | 77
2013-04-16 | 345
2013-04-15 | 34
...finds the date (first column) corresponding to the maximum value in the second column of the list box, and puts that date into a text box named Text3. Note that the CompareNumeric flag controls whether the comparison is string-based ("77" would win), or number-based (345 would win).
Private Sub Command2_Click()
Const DateCol = 0 '' column numbers start with 0
Const MaxCol = 1 '' second column has column index of 1
Const CompareNumeric = True '' convert strings to numbers for finding maximum
Dim RowIdx As Long, MaxItem As Variant, MaxIdx As Long, CurrItem As Variant, NewMaxFound As Boolean
MaxIdx = -1
MaxItem = Null
For RowIdx = 0 To Me.List0.ListCount - 1
CurrItem = Me.List0.Column(MaxCol, RowIdx)
If CompareNumeric Then
CurrItem = Val(CurrItem)
End If
If IsNull(MaxItem) Then
NewMaxFound = True '' first one
Else
NewMaxFound = (CurrItem > MaxItem)
End If
If NewMaxFound Then
MaxItem = CurrItem
MaxIdx = RowIdx
End If
Next
If MaxIdx >= 0 Then
Me.Text3.Value = Me.List0.Column(DateCol, MaxIdx)
End If
End Sub

navigating through table records in Access VBA

I have a table with two columns (value1 and value2) the values are sorted from lowest to highest. example:
Value1
20
40
43
90
100
122
Value2
4
5
9
10
15
18
I ask the user to enter an input value and then I calculate the value of CalcFinalValue which can be calculated in one of the following:
if the user input value already exist in value1 field, then return the corresponding value of in field value2. for example if the user input is 100 then CalcFinalValue will be 15
if the user input value does not exist in value1 field, then locate the two values in value1 field that the input value is between them(for example if the input value is 42, the I want to locate 40 and 43 from value1 field). Calculate CalcFinalValue as:
CalcFinalValue=(40*9)+(43*5)/42
in other words the formula will be as:
CalcFinalValue=(LowerValue of the inbetween values *lookup value of the HigherValue of the inbetween values)+(HigherValue of the inbetween values *lookup value of the LowerValue of the inbetween values)/(user input value)
I want to perform this in Access 2007 VBA.
I hope this is clear. Thanks for your help in advance!
Dim rs AS DAO.Recordset
Set rs = CurrentDb.OpenRecordset("TableName", dbOpenTable)
' inp stores the user input value; i counts the number of records that have been accessed
Dim inp, i as Integer
' r2c1 and r2c2 store the data of the second row in case the two-row calculation is needed
Dim r2c1, r2c2 as integer
' Since I mostly use forms for I/O that's what I've used here
' Change this to whatever method you use to get the user input
inp = Forms!FormName.InputTextBoxName.Value
i = 0
rs.MoveFirst
Do While (Not rs.EOF)
i = i + 1
' Check if the user input exists in the table
If (rs.Fields("Value1") = inp) Then
' Again use whatever output method you want
Set Forms!FormName.OutputTextBoxName.Value = rs.Fields("Value1")
End Do
' Otherwise, check if the current value in column 1 is greater than the input
Else If (rs.Fields("Value1") > inp) Then
' If this is true for the first row then the input is less than the lowest number.
' I assume this is out-of-bounds, but use whatever boundary condition you want
If (i = 1) Then
MsgBox("Out of Bounds", vbOkOnly)
Else
' Save the required values from this row
r2c2 = rs.Fields("Value2")
r2c1 = rs.Fields("Value1")
' Goto previous row which and calculate according to your formula
rs.MoveLast
Set Forms!FormName.OutputTextBoxName.Value = (r2c1*r2c2 + rs.Fields("Value1")*rs.Fields("Value2"))/inp
End If
End If
rs.MoveNext
Loop
' If nothing was found, the input was larger than all values in 'Value1'
If (rs.EOF) Then
MsgBox("Out of Bounds", vbOkOnly)
End If
Substitute Value1 and Value2 with whatever column names you use