I have a Visual Studio program that reads a PDF file and scrapes data from it. The VS program then generates a tab-delimited string that is manually pasted into the spreadsheet.
Everything works fine, but my tab-delimited line erases a formula in one column. Not a big deal as I just copy the formula from the previous line.
Would it be possible to put the formula into my tab-delimited line?
Here is the formula:
=IF(AND(NOT(ISBLANK($M2666)),ISBLANK($O2666)),"y","")
If I put this into the tab-delimited line in the appropriate column, it works fine, if I happen to be inserting the tab-delimited line on row 2666.
I tried using the row() function, but then it's not a valid formula:
=IF(AND(NOT(ISBLANK($Mrow())),ISBLANK($Orow())),"y","")
I tried a function that returns the last row in a given column then made a variable to put into the formula. If I am just pasting in Excel, it works, but when I try to insert it in a tab-delimited line is pastes as text.
Remember, the tab-delimited string is being generated in a program external to the spreadsheet and the program doesn't have access to the spreadsheet to find the last used row.
So, here's the question, how do I paste a formula from the clipboard?
This question is tagged as vba so here is my VBA-based solution.
dim strFormula as string
strFormula = "=IF(AND(NOT(ISBLANK(RC13)),ISBLANK(RC15)),""y"","""")"
range("M2").formular1c1 = strFormula
range("M2666").formular1c1 = strFormula
range("M9999").formular1c1 = strFormula
The Range.FormulaR1C1 property accepts the xlR1C1 style formula that will adjust for any row you place it into.
If you place the xlR1C1 style formula into a tab delimited TXT file, the following code would be necessary before and after using VBA to import the TXT file.
dim origRefStyle as long
origRefStyle = Application.ReferenceStyle
Application.ReferenceStyle = xlR1C1
'import the tab delimited TXT here
Application.ReferenceStyle = origRefStyle
You can use INDIRECT and ADDRESS... and also ROW and COLUMN:
Please search every detail on that function if you need to know.
Say you want get value of M2666 from Q2666 with the formula INDIRECT(ADDRESS(ROW();COLUMN()-4)). Back to the example problem, with assumption the formula is inserted in Q2666, then your formula should be:
=IF(AND(NOT(ISBLANK(INDIRECT(ADDRESS(ROW();COLUMN()-4))));ISBLANK(INDIRECT(ADDRESS(ROW();COLUMN()-2))));"y";"")
Please notice that Excel uses ; not , to separate parameters in a function.
Related
Suppose I have a column with many (hundreds) of rows, each with a HYPERLINK formula, e.g.
=HYPERLINK("https://npiregistry.cms.hhs.gov/registry/provider-view/99999", "99999")
How can I convert all into a cells that contain the text - but with an underlying link (as in with CTRL-K), e.g., 99999
Thanks!
After further investigation, the problem is not the security setting of the Excel for Mac but the hyperlink formula was composed with 2 cell references; the display text, and the link.
The VBA function to insert / replace a hyperlinked to a cell is as of the following.
ActiveSheet.Hyperlinks.Add Anchor:=current_range, Address:=address_string, TextToDisplay:=display_string
In your situation, you have to replace current_range, address_string, and display_string in the VBA syntax.
In my above example, since we are using a For loop to loop through all the cells in selection, you can leave it as current_range.
For the address_string, and display_string, you will feed the function with the cell location of those two on your spreadhseet. Since your spreadsheet has the address string stored in two separate columns, you want to reference to the column by either using the familiar cell reference format, Range("$C" & current_range.row) format, or use the offset method, which involve in counting the index of the column. Example, current_range.offset(0, -10).value. The -10 in the offset is how many column you want to move left from your current_range.
Note, it is important to add the .value at the back of your cell reference so it's getting the data (String) stored in the cell instead of the potential formula in the cell.
Create this macro.
Sub convert_hyperlink_formula_to_hyperlink_cell()
Dim address_string As String, display_string As String
Dim current_range As Range
For Each current_range In Selection
address_string = Mid(current_range.Formula, 13, InStr(1, current_range.Formula, ",") - 14)
display_string = current_range.value
ActiveSheet.Hyperlinks.Add Anchor:=current_range, Address:=address_string, TextToDisplay:=display_string
Next current_range
End Sub
Select the range of your Hyperlink formulas then run the macro. That should convert the hyperlink formulas to actual hyperlinked cells.
Please try this sample file.
Convert Hyperlink Sample File.xlsm
I have made a copy of your posted formula, and pasted a few lines in the sample file. The macro is already setup in the Excel file for your to test.
So one of our columns in excel has data in a cell that has subscription data, date start and date end data.
So for example:
14-Nov-2017;08-Jan-2018;Intermediate,11-Jan-2018;;Basic, 12-Jan-2018;;Basic
I would like to remove the 14-Nov-2017;08-Jan-2018;Intermediate in this example and save anything with basic value and its dates. Also coma Separated values between each data chunk.
Assuming a couple of things:
The chunks we are looking at to keep/replace are separated by a comma
The form of the chunks we wish to keep are always <date>;;Basic
In excel press Ctrl+F11 to bring up VBE (where we write VBA or "macros")
Right click, in the Project-VBAProject pane in the upper-left, on your workbook and select "Insert>>Module". This will create Module1 in the Modules folder.
Now paste in the following UDF:
Function cleancell(strCell As String) As String
For Each el In Split(strCell, ",")
If IsDate(Split(el, ";")(0)) And Split(el, ";")(2) = "Basic" Then
cleancell = IIf(cleancell = "", cleancell, cleancell & ",") & el
End If
Next
End Function
This will give your workbook a new custom formula (User Defined Formula). Save your workbook to insure the UDF is ready to go.
Assuming you have value 14-Nov-2017;08-Jan-2018;Intermediate,11-Jan-2018;;Basic, 12-Jan-2018;;Basic in Cell A1, then in A2 you can use the new formula:
=cleancell(A1)
This will spit out:
11-Jan-2018;;Basic, 12-Jan-2018;;Basic
In use:
I would like to put the below coding into a vba like a function. There is a bunch of data created already by VBA, and when the VBA does its work, then the following function should be run, but i dont know how to add to my vba so that the function always runs as long as data contains. The macro i created already puts the datasheet together, now instead of creating the below with lenthy codings, i just want my macro to run the below, like a man who clicks on the below right hand corner of the cell which contains the below function.
It should be something: Activesheet.ForulaR1C1 = "=RIGHT(AY4,LEN(AY4)-FIND(".",AY4))" something. Can someone help me? Thanks
ORIGINAL FUNCTION TO BE RUN "=RIGHT(AY4,LEN(AY4)-FIND(".",AY4))"
This is where I am at now:
Sub Project_numbers()
Dim j As Integer
Zorro = Range("AY" & Rows.Count).End(xlUp).Row
o = 4
Worksheets("MJE").Range("AF" & o).FormulaR1C1 = "=RIGHT(AE4,LEN(AE4)-FIND(".",AE4))"
o = o + 1
End Sub
You have a couple of problems here. The biggest is that you've got quotation marks in your formula. VBA reads these as the end of the string, so it's interpreting your formula as two separate text strings: =Right(AE4,LEN(AE4)-FIND( and ,AE4)), separated by a .. This isn't a structure VBA can do anything with, so it's going to fail at that point.
When you're inserting a formula with VBA that contains quotation marks, you need to use two quotes together to indicate that it's a literal quote mark that's part of the string, rather than the end of the string:
"=RIGHT(AE4,LEN(AE4)-FIND(""."",AE4))"
The second problem is that you're using the FormulaR1C1 method, which expects cell references to be given in R1C1 (row#column#) notation, rather than A1 notation, but then passing it a formula that uses A1 notation. Again, this is going to confuse the issue and produce errors.
I'm guessing you used the macro recorder to get the syntax, then inserted your own formula? The macro recorder, for some weird reason, loves to use the R1C1 reference style, but we can use a different method for written code.
The full line you need is:
Worksheets("MJE").Range("AF" & o).Formula = "=RIGHT(AE4,LEN(AE4)-FIND(""."",AE4))"
EDITED TO ADD:
With further information, specifically that you need the range referenced to change as you loop, you have some options on how to do it.
1. Use the R1C1 reference style
This allows you to include relative references in formulae easily. You'll use R to designate the formula's row, and C to designate its column; so a cell that referred to itself would simply be =RC. You can follow the R and C with numbers to designate specific rows and columns, so cell B2 would be =R2C2 - row 2, column 2. More usefully, you can use =R[#]C[#] to offset your formula by a certain amount.
In your formula, assuming it's always going to be looking at column AE but whichever row the formula is entered into, your line would be:
Worksheets("MJE").Range("AF" & o).FormulaR1C1 = "=RIGHT(RC31,LEN(RC31)-Find(""."",RC31))"
2. Build your formula from variables.
You already have a variable you can use, o, so we can combine that with the rest of the string to get the appropriate references. It's harder to read, though...
Worksheets("MJE").Range("AF" & o).Formula = "=RIGHT(AE" & o & ",LEN(AE" & o & ") - FIND(""."",AE" & o & "))"
Personally, I find this method rather cumbersome to work with, but it's an option.
3. Assign the formula to your entire range as a single operation
Personally, I prefer this option; I find it to be the neatest one. I'm assuming, from your formula, that your data starts on row 4, and you want the formula to go into every cell between AE4 and the end of your data, which is stored in Zorro. You can use this line to add the formula in one go:
Worksheets("MJE").Range("AF4","AF" & Zorro).Formula = "=RIGHT(AE4,LEN(AE4)-FIND(""."",AE4))"
The cell references will update automatically for each row. There's no need for a loop with this method - of course, if you're looping anyway, that may be no great saving.
I'm messing with a spreadsheet containing postal addresses that have been inserted in the cells' comments
Each comment contain an address composed of a variable number of lines (damn UK addresses, they can have up to 7 lines!) in the following format:
Line1,
Line2,
Line3,
[...],
State
With my poor skills, I've managed to extract the comment with a VBA script, obtaining the following string on a single cell:
Line1,Line2,Line3,[...],State
At this point each string between commas must be extracted to its own cell.
I've managed to extract the 1st 3 lines with the following formulas:
For Line1:
=LEFT(A8;(SEARCH(",";A8))-1)
For Line2:
=MID(A8; SEARCH(",";A8)+1; SEARCH(","; A8; SEARCH(","; A8)+1)-SEARCH(",";A8)-1)
For Line3:
=MID(A8; SEARCH(",";A8;SEARCH(",";A8;SEARCH(",";A8;SEARCH(",";A8)))+1)+1;SEARCH(","; A8; SEARCH(","; A8;SEARCH(",";A8)+1)+1)-SEARCH(",";A8;SEARCH(",";A8)+1)-1)
From this point I start to get overflow errors from my brain... I probably need some days of sleep.
Can anybody help me to get to "line6", and finally suggest me how to pull out the "State line" which ends without comma?
I thought I could pull out the "State" line with =RIGHT(",";SEARCH(",";A8)-1) but I'm obviously doing something wrong because that pulls out a comma instead of a string.
I guess I could do everything with a VBA script, but I'm not that skilled yet :(
With comma separated data in A1, in B1 enter:
=TRIM(MID(SUBSTITUTE($A1,",",REPT(" ",999)),COLUMNS($A:A)*999-998,999))
and copy across. For example:
Note:
Why not use TextToColumns ?
The row of formulas re-calculates automatically if A1 changes.
The row of formulas will work even if A1, itself, contains a formula.
If you are wanting to do this programmatically instead of using a built-in, check out the split function for chopping up your comma separated string. It will split up your input string into an array. Then you can do whatever you like with the array.
Dim Names() As String
Names() = Split(inputValue, ",")
For i = 0 To UBound(Names)
' do what you want with each piece
Next
Gary's Student's answer is great for using the built-in functions.
If you want a VBA solution:
Sub spitString()
Dim sourceRange As Range
Dim stringArr() As String
Dim i As Integer
Set sourceRange = ActiveSheet.Range("A1")
stringArr = Split(sourceRange.Value, ",")
For i = LBound(stringArr) To UBound(stringArr)
sourceRange.Offset(0, i + 1).Value = stringArr(i)
Next i
End Sub
You could avoid adding comments: Are you aware that users can add line breaks inside a cell by pressing ALT+RETURN?
If having high rows d is a problem and you don't like that formatting, an alternative approach might be to write a simple bit of code that changes the height of the current row when a user clicks in a certain range. It would , make other rows less high. Perhaps.
Just a thought. It has benefits keeping it simple.
Harvey.
I've pasted some numbers on Excel spreadsheet and wanted to do some calculations with it. The problem is that Excel isn't recognizing the numbers. I've already tried several methods to convert them into numbers and none of them works: paste/special multiplying by 1; formating each cell to the number/scientific number format. And there isn't also an error message on the top right corner of each cell like I've read on the internet indicating that there is a number written as text. If I retype each number, Excel recognizes it.
To make sure that the problem was really that the numbers were understood by Excel as text, I tried the functions ISNUMBER(), that returned FALSE and ISTEXT() that returned true.
I want to know how I can fix that problem without having to type into each cell.
Ps. the numbers are in scientific number format, i.e., 1,085859E+001
Since the column is text the cells are formatted as text.
you use Value to convert the text into a number so the formula will work
A2 = 123
A3 = 123 Richard
Formula
=isnumber(A2) result is false
use
=isnumber(value(A2)) result is True
I was having the same problem, until I realized that the decimal separator was set as (,) instead of (.) in the default settings. Once I changed that, everything worked fine.
If your "numbers" are being detected as text, you can use VALUE() to make sure Excel understands that it is actually a number.
A1: `1.23E+10 (this is a string)
B1: =VALUE(A1)
=12300000000
C1: 1.23E+10 (this is a number)
D1: =IF(B1==C1,"It worked", "Uh Oh")
=It Worked (for me anyway)
I'm not sure what the comma in your scientific number will do so might want to have the function replace them if there not required.
See Kenneth Hobs' answer here: http://www.vbaexpress.com/forum/showthread.php?42119-Solved-Convert-exponential-format-to-a-number
Open your Excel File, Press Alt + f11 to open the VBA screen,
Go to Insert > Module, Copy and Paste Kenneth's code:
Sub Expo()
Dim cell As Range, s() As String, lng As Long, n As Integer
For Each cell In Selection
With cell
If Not VarType(.Value2) = vbString Then GoTo NextCell
s() = Split(cell.Value2, "E")
.Value2 = s(0) * 1 * (1 * 10 ^ s(1)) 'ePart(s(1))
.NumberFormat = "General"
.EntireColumn.AutoFit
End With
NextCell:
Next cell
End Sub
You can now run it as a macro to convert selected cells. Or if you want it as a function copy this code instead:
Function Expo(cell As Range)
Dim s() As String
With cell
If VarType(.Value2) = vbString Then
s() = Split(.Value2, "E")
Expo = s(0) * 1 * (1 * 10 ^ s(1)) 'ePart(s(1))
End If
End With
End Function
This way you can use it as a normal function in excel eg =Expo(A1)
As I mentioned in the comments above though, you will have already lost some degree of accuracy when the original number was converted to scientific notation. The best solution is to get the originating program to write the proper numbers into the text file if you can.
Open a new word document and try Pasting the web content in word first, the copy this content from the word document and paste special in excel, as text. This simple solution worked for me
Open a new blank Excel, then go to Data > From Text, this way you can import text and designate which format you want to convert to. On the Text Import Wizard page, select either Delimited or Fixed width (I am not sure how your original text file look like but generally it should be Delimited. On the next page, pick a Delimiter or enter one in Others. On step 3, you should see the data listed below and the data format on the upper left. Pick General for those columns that you believe should not be Text. This should fix your problem.
My case was stubborn, no response to Paste Special or CLEAN(). Finally resolved by copying the offending column of Excel data and pasting into new Notepad++ doc. This revealed a leading "?" in all the bad numbers (apparently some non-printing character). Used Search > Replace to find all "?" and replace with nothing. Edit > Select All, copy to a new Excel column, and voilà!
There may be hidden characters. Trailing/leading spaces may not visible and hence erroneously be neglected. If there is trailing/leading Space characters with numeric values, excel consider it as text.
Copy contents problematic cells to MS-Word [(Select problematic cells and copy them to MS-Word)] and check any hidden characters, Remove hidden characters with "find"/"replace" functionality.
I was having issues with numbers from PPT (e.g. ($3,000))pasted to excel. Tried multiple different ways to get the text to recognize including find replacing parens, commas, $ signs to blank and trying to format so excel could run formulas. The only option that worked was to paste to Word first then paste value to excel which worked without any additional formatting steps. Surprised I could not do it all within excel though. Maybe there's another way
Select all the cells to convert to a number.
|Data| Menu Tab > Data Tools > [Text to columns]
Delimited. [Next]
Deselect all "Delimiters". [Next]
"Column data format" > General
[Finish]
Verify by using =ISNUMBER(C16) in an spare cell, where C16 is a sample cell. Should now return TRUE.
This happened to me lately. I had forgotten that I had set formula recalculation to manual. The weird thing is that it was returing FALSE when initially created (which was correct) but given the test depended on the value of other cells that, when changed, did not trigger the change in the cell with the isnumber() formula.
Pressing F9 "fixed" my problem (and my ignorance).