How to normalize Excel cell data - regex

I am getting the data from an external source, and I need to normalize the cells.
like this:
A
32.1342244,31.1322214,0
35.12331299999999,12.14324553333333,0
..
..
And I would like Row A to be in the form of two numbers (instead of three) and with the mantissa with 8 digits max. so the above data would look like this:
A
32.1342244,31.1322214
35.12331299,12.14324553
..
..
How can I do this? Is there a way to use a regexp for that?
Can this be done in a way to simply sanitize the data and not copy it from one place to another?

Select the cells you wish to process and run this tiny macro:
Sub Normalize()
Dim r As Range, ary
For Each r In Selection
ary = Split(r.Value, ",")
ary(0) = Format(ary(0), "0.00000000")
ary(1) = Format(ary(1), "0.00000000")
r.Value = ary(0) & "," & ary(1)
Next r
End Sub

Related

DataGridview I tried an if-else-condition in DataGridView cells

DataGridView
I tried an if-else-condition in DataGridView cells
Dim RowIdx As Integer
RowIdx = dgAttendance.CurrentRow.Index
If dgAttendance.Item(3, RowIdx).Value = "P" Or dgAttendance.Item(3,
RowIdx).Value = "P " Then
dgAttendance.Item(3, RowIdx).Value = "A"
EndIF
Please give the solution in C#. How do i use that if-else-statement in C#
Based on the example you provided in your comments - you should not call .ToString() when setting your value as this removes the reference to your cell and returns an independent value. Try this instead:
dg_attendance.CurrentCell.Value = "A";
You also probably want to access the value of the third cell in your row by something like this:
dg_attendance.CurrentRow[3].Value

Excel | Get all column/row names in which a specific text is as a list

It is difficult for me to describe the problem in the title, so excuse any misleading description.
The easiest way to describe what I need is with an example. I have a table like:
A B C
1 x
2 x x
3 x x
Now what I want is the formula in a cell for every single column and row with each of the column or row name for every x that is placed. In the example like:
A B C
1,2 2,3 3
1 A x
2 A, B x x
3 B, C x x
The column and row names are not equivalent to the excel designation. It works with an easy WHEN statement for single cells (=WHEN(C3="x";C1)), but not for a bunch of them (=WHEN(C3:E3="x";C1:E1)). How should/can such a formula look like?
So I found the answer to my problem. Excel provides the normal CONCATENATE function. What is needed is something like a CONCATENATEIF (in German = verkettenwenn) function. By adding a module in VBA based on a thread from ransi from 2011 on the ms-office-forum.net the function verkettenwenn can be used. The code for the German module looks like:
Option Explicit
Public Function verkettenwenn(Bereich_Kriterium, Kriterium, Bereich_Verketten)
Dim mydic As Object
Dim L As Long
Set mydic = CreateObject("Scripting.Dictionary")
For L = 1 To Bereich_Kriterium.Count
If Bereich_Kriterium(L) = Kriterium Then
mydic(L) = Bereich_Verketten(L)
End If
Next
verkettenwenn = Join(mydic.items, ", ")
End Function
With that module in place one of the formula for the mentioned example looks like: =verkettenwenn(C3:E3;"x";$C$1:$K$1)
The English code for a CONCATENATEIF function should probably be:
Option Explicit
Public Function CONCATENATEIF(Criteria_Area, Criterion, Concate_Area)
Dim mydic As Object
Dim L As Long
Set mydic = CreateObject("Scripting.Dictionary")
For L = 1 To Criteria_Area.Count
If Criteria_Area(L) = Criterion Then
mydic(L) = Concate_Area(L)
End If
Next
CONCATENATEIF = Join(mydic.items, ", ")
End Function

Split Pandas Column by values that are in a list

I have three lists that look like this:
age = ['51+', '21-30', '41-50', '31-40', '<21']
cluster = ['notarget', 'cluster3', 'allclusters', 'cluster1', 'cluster2']
device = ['htc_one_2gb','iphone_6/6+_at&t','iphone_6/6+_vzn','iphone_6/6+_all_other_devices','htc_one_2gb_limited_time_offer','nokia_lumia_v3','iphone5s','htc_one_1gb','nokia_lumia_v3_more_everything']
I also have column in a df that looks like this:
campaign_name
0 notarget_<21_nokia_lumia_v3
1 htc_one_1gb_21-30_notarget
2 41-50_htc_one_2gb_cluster3
3 <21_htc_one_2gb_limited_time_offer_notarget
4 51+_cluster3_iphone_6/6+_all_other_devices
I want to split the column into three separate columns based on the values in the above lists. Like so:
age cluster device
0 <21 notarget nokia_lumia_v3
1 21-30 notarget htc_one_1gb
2 41-50 cluster3 htc_one_2gb
3 <21 notarget htc_one_2gb_limited_time_offer
4 51+ cluster3 iphone_6/6+_all_other_devices
First thought was to do a simple test like this:
ages_list = []
for i in ages:
if i in df['campaign_name'][0]:
ages_list.append(i)
print ages_list
>>> ['<21']
I was then going to convert ages_list to a series and combine it with the remaining two to get the end result above but i assume there is a more pythonic way of doing it?
the idea behind this is that you'll create a regular expression based on the values you already have , for example if you want to build a regular expressions that capture any value from your age list you may do something like this '|'.join(age) and so on for all the values you already have cluster & device.
a special case for device list becuase it contains + sign that will conflict with the regex ( because + means one or more when it comes to regex ) so we can fix this issue by replacing any value of + with \+ , so this mean I want to capture literally +
df = pd.DataFrame({'campaign_name' : ['notarget_<21_nokia_lumia_v3' , 'htc_one_1gb_21-30_notarget' , '41-50_htc_one_2gb_cluster3' , '<21_htc_one_2gb_limited_time_offer_notarget' , '51+_cluster3_iphone_6/6+_all_other_devices'] })
def split_df(df):
campaign_name = df['campaign_name']
df['age'] = re.findall('|'.join(age) , campaign_name)[0]
df['cluster'] = re.findall('|'.join(cluster) , campaign_name)[0]
df['device'] = re.findall('|'.join([x.replace('+' , '\+') for x in device ]) , campaign_name)[0]
return df
df.apply(split_df, axis = 1 )
if you want to drop the original column you can do this
df.apply(split_df, axis = 1 ).drop( 'campaign_name', axis = 1)
Here I'm assuming that a value must be matched by regex but if this is not the case you can do your checks , you got the idea

"if then statement in VBA to fill cell with number"

"if then statement in VBA" I'm writing a program that puts a number in a cell in Excell if a variable reaches a certain value. I understand how to declare variables but I don't know how to tell excel to write x if A1 =34. Thanks
Add a listener to your worksheet to capture a Range. You can make the range [A1] if you are only watching a specific column/row, or you can add a range like I have below.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim KeyCells As Range
Set KeyCells = Range("A:A")
If Not Application.Intersect(KeyCells, Range(Target.Address)) _
Is Nothing Then
If Target.Value = "34" Then
Cells(Target.Row, 2) = "X"
Else
Cells(Target.Row, 2) = ""
End If
End If
End Sub
Change "x" to if you want variable x and not literal x.
If your goal is to change the value of the cell to "X" (Literal X), and you are not having macros run constantly or with each cell change, you can use the following function (or similar) in each cell in which you have a conditional.
See the Microsoft support on this topic https://support.microsoft.com/en-us/kb/213612
It's not clear what you wish to do, but let's say you want to write the current value of your variable, x, into cell B2... if cell A1 is 34.
In the above case, you would do this:
If [a1] = 34 then [b2] = x
Private Sub CommandButton1_Click()
Dim lr As Long
lr = Worksheets("New").Range("A" & Rows.Count).End(xlUp).Row
Worksheets("New").Range("T2").Formula = "=LEFT(B2,2)"
Worksheets("New").Range("T2").AutoFill Destination:=Worksheets("New").Range("T2:T" & lr)
Worksheets("New").Range("U2").Formula = "=(T2&0&0)"
Worksheets("New").Range("U2").AutoFill Destination:=Worksheets("New").Range("U2:U" & lr)
Worksheets("New").Range("V2").Formula = "=IF(AND(a2=A1,U2=U1),"",A2")" (HOW TO AUTO FILL THIS FORMULA IN A CELL)
Worksheets("New").Range("V2").AutoFill Destination:=Worksheets("New").Range("V2:V" & lr)
End Sub

Cell content inside formula

Is it possible to place the content of a cell inside a formula. By formula I mean the math formula editor (insert->object->formula).
To the best of my knowledge, there is no way to reference a cell from a formula. Math formula editor has no knowledge about OO Calc. However, you can create a new formula whenever needed using macros.
Follow thesse steps to make it work:
Put the math formula you want to insert to a cell. For example, put some numbers to cells A1, A2, A3 and put the following to cell C3:
=CONCATENATE("{";A1;"}";"over {";A2;" `+` ";A3;"}";" `=` ";A4).
This will generate something like {1} over {2 `+` 3} `= in C3
Create a macro from the code below. In OO Calc, select
Tools > Macros > Organize Macros > OpenOffice.org Basic > My Macros > Standard
Create a new macro and paste the code below.
Now you can run macro using Tools > Macros > Run Macro. Run either insertFormula which inserts math formula generated from cell C3, or addFormulaListener which will register a listener and regenerate the formula for you whenever contents of C3 changes.
Here is the code. It contains constants formulaCellFrom and formulaCellTo, which specify which cell has the math formula source and which is the target cell where the generated formula object shall be placed. Note that the target cell must be large enough for the generated formula, otherwise the macro won't delete cell's old content when regenerating the formula.
const formulaCellFrom As String = "$C$1"
const formulaCellTo As String = "$C$10"
rem ----------------------------------------------------------------------
rem Adds listener for changes of the math formula
sub addFormulaListener
dim oSheet as Object
dim oCell as Object
rem go to cell containing markup
oSheet = ThisComponent.CurrentController.ActiveSheet
oCell = oSheet.getCellRangeByName(formulaCellFrom)
rem add listener
oListener = CreateUnoListener( "formulaListener_", "com.sun.star.chart.XChartDataChangeEventListener" )
oCell.addChartDataChangeEventListener(oListener)
end sub
rem ----------------------------------------------------------------------
rem Listener for cell changes
sub formulaListener_chartDataChanged
dim oCell as Object
rem remember current cursor position
oCell = ThisComponent.CurrentSelection
rem call insertFormula
call insertFormula
rem restore cursor position
ThisComponent.CurrentController.select(oCell)
end sub
rem ----------------------------------------------------------------------
rem Creates a math formula from text in cell C1 and inserts it into cell C10
sub insertFormula
dim document as object
dim dispatcher as object
rem get access to the document
document = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
rem go to cell containing markup and copy it
dim fromCellArgs(0) as new com.sun.star.beans.PropertyValue
fromCellArgs(0).Name = "ToPoint"
fromCellArgs(0).Value = formulaCellFrom
dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, fromCellArgs())
dispatcher.executeDispatch(document, ".uno:Copy", "", 0, Array())
rem go to cell where I want the formula displayed
dim toCellArgs(0) as new com.sun.star.beans.PropertyValue
toCellArgs(0).Name = "ToPoint"
toCellArgs(0).Value = formulaCellTo
dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, toCellArgs())
rem delete previous content
dim deleteArgs(0) as new com.sun.star.beans.PropertyValue
deleteArgs(0).Name = "Flags"
rem flags: A = All, S = String, V = Value, D = DateTeim, F = Formula, ...
rem ... N = Notes, T = Formats, O = Objects
deleteArgs(0).Value = "AO"
dispatcher.executeDispatch(document, ".uno:Delete", "", 0, deleteArgs())
rem open Star.Math
oDesk = createUnoService ("com.sun.star.frame.Desktop")
dispatcher.executeDispatch(document, ".uno:InsertObjectStarMath", "", 0, Array())
rem get access to the document
document = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
rem paste clipboard using Array() as place-holder for variable name
dispatcher.executeDispatch(document, ".uno:Paste", "", 0, Array())
rem exit Star.Math
dispatcher.executeDispatch(document, ".uno:TerminateInplaceActivation", "", 0, Array())
end sub
The code was adapted from this question. Apparently, the macro must be created in My Macros and doesn't work when embedded in the spreadsheet (security measure? it just didn't work for me). The source and target cells are hardcoded but you can modify the macro to suit your needs. I'm not skilled in Visual Basic but such modifications should be easy.