Easy enough concept, but I have no idea where to start when it comes to creating a UDF, which is the only thing I can find any mention of. I have a column that populates on source sheets with either a 1 or 2. I want to do something so that all of the "1's" shows as one text entry("AA" for example) and all "2's" show as a different entry(say "BB"). Is this possible without a UDF; and if not then is there any advice on where to start?
You can use custom formatting for this. Right-click the column in question and choose "Format Cells." In the dialog, choose "Custom" and in the box at the top enter:
[=1]"AA";[=2]"BB";General
This assumes that the "1" or "2" is the sole content of the cell. Any other number or text will display in the General format.
This may help you as well. It is a conditional statement that will reference one cell the check if there is content, if not then it will put the word "None" in, otherwise it will put the contents of the cell.
=IF((Sheet1!J1089)="","None",Sheet1!J1089)
Just to update anyone else that may be interested. I have a solution that I am using. Had to go the vba route, but I've got it set up so that my macro for running reports runs the following:
Sub Conversion()
Dim X As Long, DBCodes() As String
DBCodes = Split("AA,BB,CC", ",")
For X = 1 To 3
Columns("H").Replace X, DBCodes(X - 1), xlWhole
Next
End Sub
I can change the split values and the line after for as many more values as I need replacing, though it would take fiddling with to find the point where too many values would make it impractical. Also, it makes a world of difference where I put in the line to run this; found the best spot though and even the reports that are 600+ rows the conversion only adds a couple seconds.
Related
I don't know why every time I fall in love with a program because I found it very useful at first use, but I end up always struggling of its stupidity after a depth use.
So, my journey begins with the excel function "Merge & Center" that warns me that it will only keep the top left value and delete the others, which is very stupid because I can no longer drag a function in a cell to the others, did no one in this planet suggested that it will be way easier to keep the same value in each merged cells or to put at least a simple checkbox to give the user the option to choose between the two outcomes.
Ok, before I come to this forum I did some research, found a lot of VBA codes, tricks, methods but none gave me the satisfaction that I'm looking for, I concluded that it's impossible to merge and keep values in cells, so can someone please explain to me why Microsoft didn't think of that?
Here is a simple example of what I'm looking for:
enter image description here
As you came to understand, merged cells are Excel's and VBA's worst nightmares! Avoid them (since they also make for terrible datastructures) if you can.
If you must use them and you need a function you can drag down, you'll need to make sure you create a mechanic that can skip certain rows. INDEX() is able to retrieve values with a 2nd parameter that tells the function which row you would like from a given array. If we make sure that this 2nd parameter has a steady incline we can still retrieve the correct values:
Formula in C1:
=INDEX(A:A,ROW()-1-MOD(ROW()-1,3)+1)&B1
After searching all over the internet, I didn't find the perfect solution, so I started learning VBA and I made this beautiful function, it detects if cells are merged or not and if so then it returns the top cell value.
Function Merg(CellRef As Range) As String
Dim MainCell As String
If CellRef.MergeCells Then
MainCell = Left(CellRef.MergeArea.Address, InStr(1,CellRef.MergeArea.Address, ":") - 1)
Else
MainCell = CellRef.Address
End If
Merg = Range(MainCell).Value
End Function
I don't know how to display the code properly on Stackoverflow. It's always a nightmare for me to understand the mechanics, you can visit my same thread on Microsoft Forum.
First post here, so apologies if I break any etiquette. If something is missing please let me know so I can edit my post if needed.
I'm currently working on an Excel macro, which enables me to import an interactive pdf form into excel and read data that was written in the form. Most of the script I have down by finding bits and pieces all over the internet, just one specific problem I wasn't able to solve so far.
I have one text field in my pdf that I need to split in two and save the new values in two separate cells. Not a big problem so far, but the formatting may differ, depending on the entered data, so just cutting it of after e.g. a certain amount of characters won't work. Also the quality of the user input data may not be always the same (e.g. sometimes using a hyphen between both parts of the string, using an underscore or no seperator at all). Unfortunately I can't give that text field in the pdf form a strict formatting rule, as the formatting may differ. I also cannot just make to separate form fields in the pdf file for each part of the string. The ease of use is supposed to be on the pdf user's side, not on mine...
Now, what does the data look like:
ABC-1234
ABCD-0123
A1B-12A
As you can see there is not a clear pattern. Please note that as said before the hyphen may not be there or be replaced by an underscore. I added it here to show you the separation of the two sub datasets (lets call them "Data A" for everything on the left side and "Data B" for everything on the right side of the hyphen).
The good thing! I know all the potential values Data A may have. Data B is then just supposed to be stored separately in another cell. My first train of thought was to use InStr, but that may not be the most elegant solution. Data A may be one of around 130 different values, which is also frequently growing. My excel file also has a "helper sheet", in which I store some information for e.g. dropdown menus or deadlines etc. I could store a list of potential Data A candidates here as well.
So what exactly do I need? A method to look at the string, compare it to a list of substrings (Data A, e.g. using a column in my excel sheet as data source) and store that match in Cell A1. Then take that value away from the original string so only Data B remains (I can strip away any hyphens or underscores at this point) and store this value in Cell A2.
Examples:
My import data may look like this: BER1234
Compare this to my list of match candidates, which includes "BER".
Cell A1 = "BER"
Cell A2 = (string minus the match) 1234
Import data: BERA59
Match in my candidate list: BERA
A1 = "BERA"
A2 = "59"
Import data: P9CD-1009A
Match: P9CD
A1 = "P9CD"
A2 = "1009A"
etc.
I may be able to do this with a giant block of if/else and many many InStr comparisons. Problem is, whenever I need to add a new match candidate I will have to go back to coding. It would make my life way easier if I could just e.g. add the value at the bottom of my candidate list and let the macro do it's magic.
I would love to post a piece of code here of what I did so far, unfortunately I really have no idea where to start. I do not expect a ready-to-use piece of code that I can just slab in my macro with copy and paste. If I can't understand the code, I usually go for another solution. Otherwise I can't fix it myself if anything breaks and I don't really like that approach. Giving me pointers on which functions and variable types to look at would be greatly appreciated, though. Maybe I can then piece together what I think it should look like and ask for more help after that step.
My experience level: Kind of beginner, but not total beginner. I have a basic understanding of how things work, but I'm not "fluent" in any programming languages. I know what I want to do and then usually try to get it to work by piecing together different solutions I find on the internet. So far so good, this one's a bit illusive for me, though. Any help is greatly appreciated. As mentioned before, if anything is missing or unclear, I'll gladly try to update this post.
With the suggestions I somewhat got it to work with this:
Dim wb As Workbook: Set wb = ThisWorkbook
Dim LastRow As Long
Dim x As Integer
Dim Remover As String
Dim CatNo As String
Dim Matches As Integer
With Sheets("MenuData")
LastRow = .Range("o" & .Rows.Count).End(xlUp).Row
End With
LastRow = LastRow - 4
Matches = 0
For x = 1 To LastRow
If InStr(AlbumCode1, wb.Sheets("MenuData").Range("O" & x + 4).Value) <> 0 Then
Matches = Matches + 1
Range(ColCatalog & (ImportCell.Row)).Value = wb.Sheets("MenuData").Range("O" & x + 4).Value
Remover = wb.Sheets("MenuData").Range("O" & x + 4).Value
CatNo = Replace(AlbumCode1, Remover, "")
Range(ColCatNo & (ImportCell.Row)).Value = CatNo
End If
Next
MsgBox Matches & (" Matches")
What I do is count the rows and substract 4, because my candidate list starts on row 4. Then do the loop for each x. I have declared all the Colxxx variables as Const at the very beginning of the macro. ImportCell is also declared somewhere else and working as intended for the rest of the data I import. My "Remover" is just set to the value of the match and then gets used to strip it away from the original string that is stored in AlbumCode1 (declared also at the beginning of the macro). Probably not strictly neccessary to do it this way.
So far it works. My candidates may look like this, though:
BER
BERA
If I import data like "BERA12342" I will get two matches (the MsgBox here is for checking what my code does and will be deleted later). As the candidate BERA comes after the candidate BER in my source list it's working fine, because the 2nd "match" just overwrites the first. If they were to be in a different order I would get a false match. Is there a way to only always get one match? Or will I have to make sure the source list is ordered in a certain way?
I suppose you have the candidate list in an Excel file.
If so, you can use a for each loop on the range of your candidate list
To get the full candidate list, even if it grows between two executions, you can use the first cell as a starting point and find the last cell with the toDown() method.
I don't remember its exact name but I've used it before, you can find it by recording a macro and using the Ctrl+Down shortcut.
With these two cells you have the range of your candidate list.
Try to use that formula to check if the cell contains the string:
=IF(IFERROR(FIND("string",A2,1),0)+IFERROR(FIND("string",A2,1),0)>0,"TRUE","FALSE")
source: https://best-excel-tutorial.com/59-tips-and-tricks/600-search-for-string-in-column
Then filter them out and write a for loop to move forward.
I need to get the column letters of a range for a macro. I specifically need the column letters, the numbers you get for columns directly using VBA Address functions won't work. Since the ranges are always from one column only, this simplifies the task. The range retrieved could be something like B3 or B3:B5, but always the same column and are inside a table.
So, what I need (in this case) to get would be B as a string. I tried to do the following:
RangeOfInterest = Worksheets("Sheet1").Range("Table1[Column1]").Address(0, 0)
RangeColumn = Right(RangeOfInterest, Len(RangeOfInterest) - InStr(RangeOfInterest, [0-9]))
However, I run into a series of issues with this. First, there is the InStr function. I thought this was the best way, because this function searches for the position of a character starting from the left, which is exactly what I need. However, I would need it to search for many values (any number from 0 to 9). Could I add all the numbers as search arguments or use some kind of trick to search between a range of numbers? What I tried certainly doesn't work.
On the other hand, I assume that if I somehow manage to add all numbers from 0 to 9, the function would start searching for them one by one instead of stopping the first time there is any number in the string? This would result in the issue that if for example there is a range like B3:B10 it will begin searching for a 0 and return the position of the 0 and finish, hence my code will return the string B3:B1 instead of just B.
Also, I can't just use a fixed solution like Left(RangeOfInterest, 1) to get the B because the code should work with any range, and once you reach the Z the column letters are double and go like AA, AB and so on.
I thought that another alternative would be to loop, but all my tries resulted in very complex pieces of code for what seems to have a pretty easy solution. Also, if possible, I would like to avoid looping although that doesn't matter if there is no other option. I would really appreciate any suggestion to solve this.
More often, one wants the number of a columns than its name because if you feed Excel the name it will convert it to the corresponding number for processing. Therefore I hope it isn't that you need the name for the purpose of addressing a cell using VBA. Anyway, here you go:-
Dim RangeOfInterest As String
RangeOfInterest = Worksheets("Sheet2").Range("Table1[Column1]").EntireColumn.Address(0, 0)
RangeOfInterest = Split(RangeOfInterest, ":")(0)
Debug.Print RangeOfInterest
I have a large spreadsheet with column data like:
ABC:1:I.0
ABC:1:I.1
ABC:1:I.2
ABC:1:I.3
ABC:2:I.0
ABC:2:I.1
ABC:2:I.2
ABC:2:I.3
ABC:3:I.0
ABC:3:I.2
ABC:3:I.3
ABC:4:I.0
ABC:4:I.1
ABC:4:I.2
ABC:4:I.3
ABC:5:I.0
ABC:5:I.1
ABC:5:I.2
ABC:5:I.3
ETC.
I need to replace the above with the following:
ABC:I.Data[1].0
ABC:I.Data[1].1
ABC:I.Data[1].2
ABC:I.Data[1].3
ABC:I.Data[2].0
ABC:I.Data[2].1
ABC:I.Data[2].2
ABC:I.Data[2].3
ABC:I.Data[3].0
ABC:I.Data[3].2
ABC:I.Data[3].3
ABC:I.Data[4].0
ABC:I.Data[4].1
ABC:I.Data[4].2
ABC:I.Data[4].3
ABC:I.Data[5].0
ABC:I.Data[5].1
ABC:I.Data[5].2
ABC:I.Data[5].3
ETC.
Here is a sample of the data, most of the data follows a similar format with the exception of the naming "ABC", which can vary in size, so it might be "ABCD" and also with the exception of the letter "I", it can be "O" as well. Also, some might be missing some values such as ABC:3:I.1 which is missing from the data. I am not too familiar with excel formulas or VBA code. Does anyone know how to do this? I have no preference on which method it has to be done in as I don't mind learning some VBA code if someone provides me with a VBA solution.
I was thinking of using some sort of loop along with some conditional statements.
Thanks!
Please try:
=LEFT(F11,FIND(":",F11))&MID(F11,FIND(":",F11,6)+1,1)&".Data["&MID(F11,FIND(":",F11,2)+1,1)&"]."&RIGHT(F11,1)
copied down to suit, assuming placed in Row11 and your data is in ColumnF starting in Row11.
Curiosities:
When this A was first posted it attempted to address only the tabulated example input and output. I temporarily deleted that version while addressing that what was in the table as ABC might at times be ABCD and that what was I might at times be O.
OP has posted an answer that I edited to make no visible change but which shows as the deletion of two characters. A copy of the OP’s formula exhibited a syntax error prior to my edit.
OP suggested an edit to my answer but this was rejected by the review process. As it happens, I think the edit suggestion was incorrect.
I have edited my answer again to include these ‘curiosities’ and to match the cell reference used by the OP in his answer.
=LEFT(A1,SEARCH(":",A1)) & MID(A1, SEARCH(".",A1)-1, 2) &
"Data[" & MID(A1,SEARCH(":",A1)+1,1) & "]" & RIGHT(A1,2)
With the help of pnuts I was able to come up with my own solution:
=LEFT(F11,LEN(F11)-5)&MID(F11,LEN(F11)-2,2)&"Data["&MID(F11,LEN(F11)-4,1)&"]"&RIGHT(F11,2)
My solution works based on the fact that the length of the last six values in the string ABC:1:I:0 will always be the same in size for all the data I have, hence you see LEN(F11)-some number in my code. The only part of the string that changes in size is the first part, in this case ABC which can also be ABCDEF, etc.
If you'd like to use formulas rather than VBA, an easy option is to split the data into 4 columns, using the Text To Columns option - first split using the colon as a delimiter, then using a full-stop / period as a delimiter.
Once you have 4 columns of data (one for each block), you can use the Concatenate function to join them and add in the extra characters: =CONCATENATE(A1,":",C1,".","Data[",B1,"].",D1)
This should still work if you have extra / alternative characters (eg ABCD instead of ABC), as long as you have the same delimiters, but obviously you'd need to test to make sure.
33266500,332665100,332665200,332665300 was the original value, cell should look like this: 33266500,332665100,332665200,332665300 but what I see as the cell value in excel is 3.32665E+34
So the question is I want to convert it into the original string. I have found format function on google and I used it like these
format(3.32665E+34,"standard")
giving it as 332,6650,033,266,510,000,000,000
How to parse it or get back the orginal string? I belive format is the function in vba.
Excel has a 15 digit precision limit. If the numbers are already shown like this when you access the file, there is no way to get the number back - you have already lost some digits. VBA code and formulas will not help you.
If this is not the case, you can add a single quote ' mark before the number to store it as text. This will ensure Excel does not try to treat it as a number and thus lose precision.
If you want the value kept exactly, store the data as a string, not as a number. The data type you are using simply doesn't have the ability to do what you are asking it to do.
If you're starting with an Excel file that has already been created then you've already lost the information: Excel has tried to understand what it was given and its best guess has turned out to be wrong. All you can do (if you can't get the source data) is go back to the creator of the Excel file and tell them what's wrong.
If you're starting with, say, a text file that you're importing, then the news is much better:
If you're importing manually using the Text Import Wizard, then at "Step 3 of 3" you need to set "Column Data Format" for the problem field to "Text".
If you're using a macro, you'll need to specify a value for the TextFileColumnDataTypes property that does the same thing. The easiest way to get it right is to use the Macro Recorder.
If you want the four values in the string to be separate cells, then again, look at the Text Import Wizard settings: in Step 1 of 3 you need to set "Delimited" data type (usually the default) and in Step 2 make sure that "Comma" is checked.
The value needs to be entered into the cell as a string. You need to make whatever it is that inserts the value preceed the value with a '.