Check the length of data in a cell and add a zero - vba

I have a spreadsheet containing data in the following format:
Col1 Col2
ROW1: 21211 Customer 3873721
ROW2: 101111 Customer 2321422
ROW3: 91214 Customer 2834712
ROW4: 231014 Customer 3729123
I need to be able to create a macro that goes through each row and determines the number of characters that make up the row1 data.
For example:
If data contained in the first cell or ROW1 consisted of a total of 6
characters then this will remain the same. If it consisted of 5
characters then a zero needs to be added to the front of it.
I'm using Excel 2003.

VBA is not needed in this case. A simple IF Statement should do the trick. Assuming the column you want to evalutate is column A place this in column B and duplicate down the column:
=+IF(LEN(A1)=5,"0" & A1,A1)
This will work provided all values are 5 or 6 characters long as it appears in your sample data.

It seems OP may be happy with a Custom Format of:
#000000
This is easy to apply but mainly may be a good idea because most other ways of prepending a 0 are only possible by conversion of numeric values to strings (as otherwise Excel will automatically strip leading zeros). If that is done selectively (for length 5 but not length 6) a column of what appears to be numbers might end up with mixed types (of different behaviour) and so confuse or inconvenience.

Related

Varying Format "Part Number" sort issue

(Current Sort Sample:)
2-1203-4
2-1206-3
2CM-
3-1610-1
3-999
…
AR3021-A-7802
AR3021-A-7802-1
B43570-
B43570-3
I am working on an 8000+ record parts list. The challenge I am running into is that different manufactures of the parts are using many varying formats for their part numbers. “Part Number” is the field I wish to sort my entire worksheet on. (There are about 10 columns of data in this worksheet.)
My methodology for attacking this challenge was to count the number of characters to the left of any “-“ and count the total number of numeric characters in the field. (I also set “Part Numbers” that started with a non-numeric character to a count value of 99 for both count calculations so those would sort after the numeric values.) From this, I was able to sort on the values to the left of the “-“ using .the MIN of the two counts. (My “Part Numbers” are in Column B and I have a header row which means that my first “Part Number” is in cell B2.)
This method worked up to a point. My challenge is that I need to subsequently sort values after the “-“ character as is illustrated by the erroneous sort of “3-1610-1” being followed by “3-999”
One of the limitations I see is that sorting with  Data  Sort only gives three columns to sort on. To sort on just the characters to the left of the “-“ is costing me those three columns. So, I am unable to repeat the whole process of counting values after the “-“ character and subsequently sorting with  Data  Sort after running the primary sort.
Has the sort of many differing formats of a field such as “Part Number” been solved? Is there a macro that can be applied to this challenge? If so, I would be grateful for your input.
This data is continuously updated with new part numbers so the goal here is to be able to add those additional part numbers to the bottom of the worksheet and use a macro to correctly resort the appended list.
For the record, I am not married to my approach. After all, it didn’t solve my challenge!
Thank you,
Darrell
Place this procedure in a standard code moule:
Public Sub PartNumberSortFormat()
Dim i&, j&, f, vIn, vOut
vIn = [b2:index(b:b,match("*",b:b,-1))]
vOut = vIn
For i = 1 To UBound(vIn)
f = Split(Replace(vIn(i, 1), " ", ""), "-")
For j = 0 To UBound(f)
If IsNumeric(f(j)) Then
f(j) = Format$(f(j), "000000")
Else
f(j) = String$(6 - Len(f(j)), "0") & f(j)
End If
Next
vOut(i, 1) = Join(f, "-")
Next
Columns(1).Insert xlToRight
[a1] = "SORT COLUMN"
[a2].Resize(UBound(vOut)) = vOut
Columns(1).EntireColumn.AutoFit
End Sub
After running the procedure, you will notice that it has inserted a new column A on your worksheet and your data has been scooted over to the right by one column.
This new column A will contain a copy of your part numbers, reformatted in such a fashion to allow normal sorting.
Now select all of the data INCLUDING this new column A and sort A-Z on column A.
After the sort, you may delete the new column A.
This works by padding all characters surrounding dashes to six zeroes.
My Thoughts:
Excel 2010 onwards lets you sort using as many columns as you like. (Not sure about 2007). Don't know which version you have!
You could use the formula SUBSTITUTE to remove all "-" from the part number then sort on the number that remains, which gives you a order more like the one you are wanting.
eg
Value =SUBSTITUTE(B2,"-","")
3-15 315
3-888 3888
3-999 3999
3-1610 31610
3-2610 32610
3-1610-1 316101
3-2610-3 326103
It's not exactly what you need though!
Combine this with other formulas (or a VBA function) to manipulate you part number to be more sortable.
You could use FIND to find the position of the first "-" and extract the numbers before it into one column.
Similarly using FIND, MID and LEN you could extract the numbers between a part number two "-".
I suspect if will be best to write a VBA function to convert a part number into a "sortable value". This might splitting the part number into it's component bits (ie each bit being the text between the "-")
(VBA function split might useful for this. It creates an array.
If you know the formats of ALL the part numbers that can be delivered, you can code accordingly.
I suspect you code will take a numbers like and convert them as shown
AB123-456-78 AB12300456007800
AB12-45-7 AB12000450007000
AB12-45 AB12000450000000
ie padding with zeros each component of the part number
The key to sorting the TEXTUAL values into the order you want is understanding how textuals values get sorted! Do some experiments. Then create zero (or "9") padded numbers that sort the numbers as you required.
I hope this helps.
While not a technical answer to the Excel question, I am a logistician working with extremely large data sets of part numbers - always varying in format. The standard approach used in my field is to "ignore" (remove) special characters from the P/N and append the (clean) P/N to the 5-digit CAGE (manufacturer) code to create a "unique" CAGE + (clean) P/N code for sorting, lookup, etc. Create a column for that construct.

VBA to check for blank cells in columns based on value in another column

Given
O 1 2 3 A
A 4 5 6 B
B 7 8 9 D
O 3
C 15
T 18
I'm looking for VBA code to validate that when column A contains a value that the remaining columns also contain values and when it doesn't contain a value, that columns 2 & 5 also contain values but 3 & 4 don't.
I've simplified the example, in a real sheet there will be many more columns and rows to check.
I've considered COUNTIF and INDEX/MATCH and array forumlas but from my understanding these all work on single columns at a time.
I want to do something like WHEN A1:An<>"" THEN COUNTBLANK(B:E) ELSE COUNTA (C:D)
Is the best way to use autofilter using blanks in A and then countblank and then a second autofilter for values in A.
Thanks
You can do it with a couple of nested IF formulae as follows:
=IF(A1<>"",
"A not empty, "&IF(COUNTBLANK(B1:E1)=0,
"B:E not blank",
"B:E have blanks"),
"A blank, "&IF(AND(COUNTBLANK(B1)+COUNTBLANK(E1)=0,
COUNTBLANK(C1)+COUNTBLANK(D1)=2),
"Columns 2&5 have values and Columns 3&4 don't",
"but condition not met"))
The reason for going down the VBA route is that I want a generic reusable function as opposed to a formula I copy between cells and sheets changing the columns etc along the way ending up with a lot of duplicate code.
So something that takes a column to test and a value to test it with. Third parameter would be a range of columns to validate, and the fourth parameter the validation.
I don't want any solution to have the columns hard coded and I don't want intermediate totals at the end of rows. This is fairly easily achieved in Excel itself...
The reason for trying to use countblank is that I can apply it to a range.
After a lot of searching I discovered this (the columns don't match the original example)
=SUMPRODUCT((A2:A19<>"")*(B2:D19=""))
=SUMPRODUCT((A2:A19="")*(D2:D19=""))
=SUMPRODUCT((A2:A19="")*(B2:C19<>""))
Nice huh? I just need to convert it into VBA now.
Thanks

copy only those rows whose string len is > 6 in b column cell values

is it possible to copy only those rows which has string length more than 6 characters and paste them to a new sheet? The task is I have to remove all the unwanted characters in the rows. the range is 2 to 4000 something like that
I was using looping and mid function to do that which i found on google because I found only looping solution to that on google, because I only need numbers in each cell of B column and remove all other character except &,/, ,,. Then after cleaning up all ce
lls in B column I need to check the number of digits in each row of B column and if it contains more than 6 it should be copied to new sheet and it may contain blank cells too in between
a b c
6451 1234567 somevalue
4563 12345 somevalue
3245 123456789 somevalue
2345 1234 somevalue
Now I have to copy the 1 and 3 rd row but not the other rows as length of string is less than 7. I have to check only the B column and copy the entire row if it has more than 6 digits
I think what your boss is trying to say (not very well, btw) about using variant arrays, etc. instead of worksheets is to keep it in VBA. Read in the data once and manipulate it within VBA instead of pasting and manipulating data on a worksheet to get the desired result. This of course extends to anything outside of making calls to Excel, not just variant arrays. Perhaps you are often looping through cells one by one and he is trying to say he'd prefer if you dumped a range into a variant array and worked on it inside of VBA instead.
Of course, the best method depends on the task on hand, in my opinion.
As for your row question, it's a little unclear what you're trying to do (try to be careful how you use the words 'row' 'cell' and 'column'). A row cannot have a 'string length' so I am assuming you mean cell. Please confirm.

Excel 2007 several columns with different values, find where which number is

I Have 6 columns where I have up to 320 values. I say up to because the number of values differ in each column and the values also differ in the columns.
Like this:
Column A has the following values, one in each cell: 1,2,3,4,6,8,9
Column B has the following values, one in each cell: 1,3,4,6,7,8,10
etc.
I would like to know what numbers that differ between the columns, so I would like to know that 2 is missing in the B column and that 9 is missing from the A column.
Optimal would be if it were possible to have one line for each number and when there is missing I just get a blank cell on that line in that specific column.
Keep in mind that there are 6 columns.
Is this possible? Is there a workaround?
I would prefer to do this in Excel but I can use other solutions as well as long as it solves my problem.
If I understand your question correctly the following might help. (I'm assuming no header row here)
In column G put the numbers 1 to 320, e.g. 1,2,3,4,5,6,...320 - so this takes up 320 rows.
In cell H1 put the following:
=VLOOKUP($G1,A:A,1,0)
Drag the above formulae across 6 columns - so H1 to M1 and then select the 6 cells (H1:M1) and drag them down to row 320.
In the missing numbers cells you will get a "#N/A" display so you could replace the above vlookup and use an if condition if you want. Something like:
=IF(ISERROR(VLOOKUP($G1,A:A,1,0)),"",VLOOKUP($G1,A:A,1,0))
Hope this helps.

Excel countif Pulling apart a cell to do different things

Excel 2007
I have a row of cells with variation of numbers and letters (which all mean something.. not random.)
It's basically a timesheet. If they take a sick day they put in S, if they take a partial sick day they put in PS. The problem is they also put in the hours they did work too. They put it in this format: (number)/PS.
Now if it were just letters I could just do =countif(range,"S") to keep track of how many s / ps cells there are. How would I keep track if they are PS where it also has a number separated by a slash then PS.... I also still need to be able to use that number to add to a total. Is it even possible or will I have to format things different to be able to keep track of all this stuff.
Assuming this is something like what your data looks like:
A B C D E
1 1 2 S 4/PS 8
...then you could do this:
1- add a column that just totals the "S" entries with a COUNTIF function.
2- add a hidden row beneath each real data row that will copy the numerical part of the PS entries only with this function in each column:
=IF(RIGHT(B1,2)="PS",IF(ISERROR(LEFT(B1,LEN(B1)-SEARCH("/",B1)-1)),"",INT(LEFT(B1,LEN(B1)-SEARCH("/",B1)-1))),"")
3- add another column to the right that just totals the "PS" entries by summing the hidden row from step 2.
3- add another column that totals everything by just summing the data row. that will ignore the text entries automagically.
4- have a grand total column that adds those three columns up
If you don't want to see the "S" and "PS" total columns, you can of course just hide them.
So in the end, the sheet would look like this:
A B C D E F G H I J
1 1 2 S 4/PS 8 1 4 11 16
2 4 <--- hidden row
HTH...
My quick take on this is:
pass the cell value into a CSTR function, so no matter what is entered you will be working with a string.
parse the information. Look for S, PS, or any other code you deem to be valid. Use Left or Right functions if you need to look at partial string.
check for number by testing the ascii value, or trying a CINT function, which will only work if the string can be converted to integer.
If you can show a sample of your cells with variation of numbers and letters I can give you more help. Hope this works out.
-- Mike