I found a macro (courtesy of Jerry Beaucaire) that splits up one worksheet into many based on unique values in a given column. This works great. However...
The client has supplied a differently formatted worksheet which needs some gentle massaging to get into the format we need.
First, let me show you a snippet of JB's code:
MyArr = Application.WorksheetFunction.Transpose _
(ws.Columns(iCol).SpecialCells(xlCellTypeConstants))
From what I can tell (and I'm a total VB newbie, so what do I know..??), this populates an array with the selected row values
And this:
For Itm = 2 To UBound(MyArr)
...(code removed)
ws.Range("A" & TitleRow & ":A" & LR).EntireRow.Copy _
Sheets(MyArr(Itm) & "").Range("A1")
...(code removed)
Next Itm
...seems to do the copying.
Alright. ...fine so far.
The problem is that I need to add a step to the process. This will be tricky to explain. Please bear with me...
Title row is row 1
Data starts in row 2
Each row has 9 columns:
colA: identifier
colB-colD: x,y,z values (for top of item)
colE-colG: x,y,z values (for bottom of item)
colH and colI: can be ignored
These x,y and z values are used to define points that are used to plot lines in a 3D modelling program. Each row in the worksheet actually defines a line (well... a start point and an end point - "top" and "bottom") Unfortunately, the data(worksheet) we have received defines two sets of data for each line - both having the same start point, but with different end points. Put another way, starting with rows 3 and 4, the data in columns B-D is the same for both rows. This applies to rows 5 & 6, 7 & 8, etc.
Since all we need are a set of data POINTS, we can safely use the values from cols E-G.
HOWEVER... and this is where I need help... We need the first row of the newly created worksheet to start with the values from row 2, cols B-D. (ie. we can use the end points as our coordinates, but we still need the first start point) All the rest is fine the way it is.
For example:
Source Data:
| A | B | C | D | E | F | G |
1 | id | x-top | y-top | z-top | x-bottom | y-bottom | z-bottom |
2 | H1 | 101.2 | 0.525 | 54.25 | 110.25 | 0.625 | 56.75 |
3 | H1 | 110.25| 0.625 | 56.75 | 121.35 | 2.125 | 62.65 |
4 | H1 | 110.25| 0.625 | 56.75 | 134.85 | 3.725 | 64.125 | B,C,D same as row 3
5 | H1 | 134.85| 3.725 | 64.125| 141.25 | 4.225 | 66.75 |
6 | H1 | 134.85| 3.725 | 64.125| 148.85 | 5.355 | 69.85 | B,C,D same as row 5
What I need:
| A | B | C | D | E | F | G |
1 | id | x-top | y-top | z-top | x-bottom | y-bottom | z-bottom |
2 | H1 | | | | 101.2 | 0.525 | 54.25 |
3 | H1 | 101.2 | 0.525 | 54.25 | 110.25 | 0.625 | 56.75 |
4 | H1 | 110.25| 0.625 | 56.75 | 121.35 | 2.125 | 62.65 |
5 | H1 | 110.25| 0.625 | 56.75 | 134.85 | 3.725 | 64.125 |
6 | H1 | 134.85| 3.725 | 64.125| 141.25 | 4.225 | 66.75 |
7 | H1 | 134.85| 3.725 | 64.125| 148.85 | 5.355 | 69.85 |
So... What's the best way to do this? Can I add to the existing macro to perform this operation? If so, better to modify the array? ...better to modify the Copy routine? ...and how??
Thanks in advance for your help and please don't suggest doing it manually. There are 70,000+ rows to parse!
If you need more info, let me know!
The full macro is available for free to all at this location
To achieve your connecting points, these additions should do it:
For Itm = 2 To UBound(MyArr)
...(code removed)
ws.Range("A" & TitleRow & ":A" & LR).EntireRow.Copy _
Sheets(MyArr(Itm) & "").Range("A1")
Sheets(MyArr(Itm) & "").Rows(2).Insert xlShiftDown
Sheets(MyArr(Itm) & "").Range("E2").Resize(, 3).Value = Sheets(MyArr(Itm) & "").Range("B3").Resize(, 3).Value
...(code removed)
Next Itm
Related
What is the best way for storing enumerated fields with ability to change its order?
Lets say my database looks like this:
| Table |
|---------------------|
| id | name | order|
| 1 | 1st | 1 |
| 2 | 2nd | 2 |
| 3 | 3rd | 3 |
| 4 | 4th | 4 |
Now, when user change order in such a away
| Table |
|---------------------|
| id | name | order|
| 1 | 1st | 1 |
| 4 | 4nd | 2 |
| 2 | 2nd | 3 |
| 3 | 3rd | 4 |
Here I would have to update all rows in this table.
I consider 2 solutions
Solution 1)
When inserting row X between for example order 2 and order 3, I would change row's X order field to 3.5, So I would choose number in the middle between adjacent orders.
Above table would look like this
| Table |
|---------------------|
| id | name | order|
| 1 | 1st | 1 |
| 4 | 4nd | 2.5 |
| 2 | 2nd | 2 |
| 3 | 3rd | 3 |
Then, after for example 16 changes I would update table and normalize all order fields, so table after normalization would be like this:
| Table |
|---------------------|
| id | name | order|
| 1 | 1st | 1 |
| 4 | 4nd | 2 |
| 2 | 2nd | 3 |
| 3 | 3rd | 4 |
Solution 2)
I also consider adding fields "next" (or "next" and "prev") to each row, but it looks for me like waste of memory.
I really dont want to update whole table every time somebody change order. What is the best way of solving this problem?
my google sheet excel document contain data like this
+---+---+---+---+---+---+
| | A | B | C | D | E |
+---+---+---+---+---+---+
| 1 | | c | | x | |
+---+---+---+---+---+---+
| 2 | | r | | 4 | |
+---+---+---+---+---+---+
| 3 | | | | m | |
+---+---+---+---+---+---+
| 4 | | | | | |
+---+---+---+---+---+---+
Column B and D contain data provided by IMPORTRANGE function, which are store in different files.
And i would like to fill column A with first not empty value in row, in other words: desired result must look like this:
+---+---+---+---+---+---+
| | A | B | C | D | E |
+---+---+---+---+---+---+
| 1 | c | c | | x | |
+---+---+---+---+---+---+
| 2 | r | r | | 4 | |
+---+---+---+---+---+---+
| 3 | m | | | m | |
+---+---+---+---+---+---+
| 4 | | | | | |
+---+---+---+---+---+---+
I tried ISBLANK function, but apperantly if column is imported then, even if the value is empty, is not blank, so this function dosn't work for my case. Then i tried QUERY function in 2 different variant:
1) =QUERY({B1;D1}; "select Col1 where Col1 is not null limit 1"; 0) but result in this case is wrong when row contain cells with numbers. Result with this query is following:
+---+---+---+---+---+---+
| | A | B | C | D | E |
+---+---+---+---+---+---+
| 1 | c | c | | x | |
+---+---+---+---+---+---+
| 2 | 4 | r | | 4 | |
+---+---+---+---+---+---+
| 3 | m | | | m | |
+---+---+---+---+---+---+
| 4 | | | | | |
+---+---+---+---+---+---+
2) =QUERY({B1;D1};"select Col1 where Col1 <> '' limit 1"; 0) / =QUERY({B1;D1};"select Col1 where Col1 != '' limit 1"; 0) and this dosn't work at all, result is always #N/A
Also i would like to avoid using nested IFs and javascript scripts, if possible, as solution with QUERY function suits for my case best due to easy expansion to another columns without any deeper knowladge about programming. Is there any way how to make it simply, just with QUERY, and i am just missing something, or i have to use IFs/javascript?
try:
=ARRAYFORMULA(SUBSTITUTE(INDEX(IFERROR(SPLIT(TRIM(TRANSPOSE(QUERY(
TRANSPOSE(SUBSTITUTE(B:G, " ", "♦")),,99^99))), " ")),,1), "♦", " "))
selective columns:
I am working on building data historical of Financial System.
I need a macro that reads if the cell doesn´t contain uppercase, then concatenates the text of this cell with the previous value that was uppercases.
| FIRST STEP |
|------------------|
| | Name |
| --- | ---------- |
| 1 |DISPONIBLE: |
| 2 |Caja |
| 3 |Bancos |
| 4 |INVERSIONES:|
| 5 |Temporales |
| 6 |Largoplazo |
| 7 |CARTERA: |
| 8 |Crédito |
| | LAST STEP |
|----------------------------|
| | Name |
| --- | -------------------- |
| 1 |DISPONIBLE: |
| 2 |disponibleCaja |
| 3 |disponibleBancos |
| 4 |INVERSIONES: |
| 5 |inversionesTemporales |
| 6 |inversionesLargoplazo |
| 7 |CARTERA: |
| 8 |carteraCrédito |
This should do it:
Sub t()
Dim rng As Range, cel As Range
Dim capitalWord As String
Set rng = Range("A1:A8") 'Adjust as needed
For Each cel In rng
If IsUppercase(cel.Value) Then
capitalWord = Replace(cel.Value, ":", "")
Else
cel.Value = LCase(capitalWord) & WorksheetFunction.Proper(cel.Value)
End If
Next cel
End Sub
Public Function IsUppercase(AString As String) As Boolean
IsUppercase = (UCase(AString) = AString)
End Function
Basically it checks if the cell is uppercase, and if so, sets that as the capitalWord. Otherwise, adds the lowercase of that word to the cell value.
I was wondering if you can help me with the following problem in spss syntax.
My dataset has nested structure.
Data are nested in companies, then each company has 1 or 2 bosses, but in this case I care only about boss 1. At a previous stage in time the boss graded the workers (not all of them). Now, the ID and the grade of the workers is on the row each worker.
I would like to move the information that was obtained during worker's assessment and create new sets of variables for each (worker ID and grade) on the line/row of the boss.
+---------+------+--------+--------------+---------+---------+--------+---------+
| company | boss |workerID|worker's grade|N:workID1|N:grade1 |N:work2 |N:grade2 |
+---------+------+--------+--------------+---------+---------+--------+---------+
| A | 1 | 1 | | 3 | A | 4 | A |
| A | 2 | 2 | | | |
| A | 0 | 3 | A | | |
| A | 0 | 4 | A | | |
| A | 0 | 5 | | | |
| B | 1 | 1 | | 3 | B | 4 | A |
| B | 0 | 2 | | | |
| B | 0 | 3 | B | | |
| B | 0 | 4 | A | | |
| C | 1 | 1 | | 2 | D | -1 | -1 |
| C | 0 | 2 | D | | |
I would like to move the worker's id and the grade that to the row of the boss in the NEW variables, without loosing the existing variables on workerID and worker's grade.
Basically, I will need to feed forward the information into the new variables and to the row of boss EQ 1 separately for each company.
I have no idea how to proceed with this. I assume that I need a loop that creates new variable for each worker ID that has a valid grade and then feeds forward the information from the worker's row to the boss' newly generated variables.
Any suggestions are very wellcome :-)
Take a look at VARSTOCASES (Data > Restructure)
I am having a logic issue in relation to querying an SQL database. I need to exclude 3 different categories and any item that is included in those categories; however, if an item under one of those categories meets the criteria for another category I need to keep said item.
This is an example output I will get after querying the database at its current version:
ExampleDB | item_num | pro_type | area | description
1 | 45KX-76Y | FLCM | Finished | coil8x
2 | 68WO-93H | FLCL | Similar | y45Kx
3 | 05RH-27N | FLDR | Finished | KH72n
4 | 84OH-95W | FLEP | Final | tar5x
5 | 81RS-67F | FLEP | Final | tar7x
6 | 48YU-40Q | FLCM | Final | bile6
7 | 19VB-89S | FLDR | Warranty | exp380
8 | 76CS-01U | FLCL | Gator | low5
9 | 28OC-08Z | FLCM | Redo | coil34Y
item_num and description are in a table together, and pro_type and area are in 2 separate tables--a total of 3 tables to pull data from.
I need to construct a query that will not pull back any item_num where area is equal to: Finished, Final, and Redo; but I also need to pull in any item_num that meets the type criteria: FLCM and FLEP. In the end my query should look like this:
ExampleDB | item_num | pro_type | area | description
1 | 45KX-76Y | FLCM | Finished | coil8x
2 | 68WO-93H | FLCL | Similar | y45Kx
3 | 84OH-95W | FLEP | Final | tar5x
4 | 81RS-67F | FLEP | Final | tar7x
5 | 19VB-89S | FLDR | Warranty | exp380
6 | 76CS-01U | FLCL | Gator | low5
7 | 28OC-08Z | FLCM | Redo | coil34Y
Try this:
select * from table
join...
where area not in('finished', 'final', 'redo') or type in('flcm', 'flep')
Are you looking for something like
SELECT *
FROM Table_1
JOIN Table_ProType ON Table_1.whatnot = Table_ProType.whatnot
JOIN Table_Area ON Table_1.whatnot = Table_Area.whatnot
WHERE Table.area NOT IN ('Finished','Final','Redo') OR ProType.pro_type IN ('FLCM','FLEP')
Giving the names of the three tables and the joining criteria will help me improve the answer.