For example, suppose I have this Excel file.
Then, I am manually putting things on Excel into do file like this.
replace A = 1 if B>=1 & B<=6
replace A = 2 if B>=23 & B<=2
replace A = 3 if B>=3 & B<=1
replace A = 4 if B>=5 & B<=3
If this wasn't clear, please see this image to see what I am doing.
But there could be actually hundreds of lines.
How can write a short code which imports the Excel file, and another short code which replaces the manual codes I have written?
So the goal here is just to make my code succinct.
You can import excel this file. Let's suppose the headers are A and B and the import produces those as numeric variables. Then the text of a new do-file is contained within
gen text = "replace A = " + string(_n) + " if inrange(A, " + string(A) + "," + string(B) + ")"
which you must export and then run on your real data.
Not tested. I'd also suggest considering doing this in your favourite text editor.
Note that many of your comparisons in your example will always be false.
Related
I have a text file containing danish characters
"Næsby IF afdeling * Badminton * Sport *"
When splitting and placing them in an array the danish characters gets "messed up"
This is the complete Text string in a *.TXT file to be split up in Excel columns:
"Ulrich*wiingreen*BenPauWin05 Aps*Søballehøjen 12*5270*Odense N*+4530212215*ulrich#wiingreen.eu*Næsby IF afdeling*Badminton*Sport* *Hal 1*Hal 2*99*11/03/2022 13:00*11/03/2022 17:00*kkkk"
The code doing this is:
If InStr(FileName, "forespoerg_") <> 0 Then
OrderArr = Split(OrderDetails, "*")
OrderRow = OrdersDB.Range("A99999").End(xlUp).Row + 1
OrdersDB.Cells(OrderRow, 1).Value = Application.WorksheetFunction.Max(Range("A4:A9999")) + 1
OrdersDB.Cells(OrderRow, 2).Value = Date
For OrderCol = 3 To 20
OrdersDB.Cells(OrderRow, OrderCol).Value = OrderArr(OrderCol - 3)
Next OrderCol
End If
The splitting works just fine. Unfortiunately the characters gets messed up.
Example: "Søballehøjen 12" imports as: "Søballehøjen 12"
Can anyone give a hint to solve this character issue.
Not sure but I suspect encoding mismatch. You can try opening your text file with VS Code and watch at the bottom right what is its encoding.
You can then use StrConv(yourTextVar, someconversion) wher someconversion is a value like vbUnicode or vbFromUnicode (see options here)
How do you import the text file ? If your file is a unix or another non Windows flavour you could try reading the file using an ADODB.Stream, which offers fine control on the encoding. I quickly found a sample here.
I've seen a few answers to this problem, but in VBA and C#---nothing in python.
In python 3, I'm trying to do the following:
Assign a variable a string of values with appropriate "excel" format
Have this variable then copied to the clipboard
Then the user should be able to manually CTRL+V (paste) this string into excel and have it separate into the correct row/column placements.
I'm using both tkinter and openpyxl for my project and through testing I've gotten some results, but it is not what I want. The closest that I've gotten is below.
# If I first go into excel,
# and copy a few columns within a single row with different data in them,
# then I run the following code:
import tkinter as tk
root = tk.Tk()
paste = root.clipboard_get()
print(paste)
# Then I manually copy the print output to the clipboard,
# and then go back to excel and paste,
# excel gives the following warning message:
# "The data you're pasting isn't the same size as your selection. do you want to paste anyways?"
# And after pressing OK, it seems as though the data is pasted properly.
This is OK, and the print(paste) string might help me create the appropriate format for the initial variable of strings that I want to generate, but I need a solution that will not cause Excel to make this warning sign pop up every time.
If anyone can provide some insight into this, I would greatly appreciate it. Also, the solution needs to be via python not through modifications to Excel. Secondly, the solution is not about appending/writing the data directly to Excel (via Openpyxl, etc) but about getting the data to the clipboard in the appropriate format (I'm using Excel 2016).
Thanks!!
Edit:
I have also tried using the "ctypes solution" presented here by user kichik.
To make this solution easier to work with, I downloaded an app called "InsideClipboard" which lets me easily see the format ID of each types of formats that the clipboard "copies" data in.
Using kichik's ctype solution, I checked to see if manually copying the print output of the different formats stored in the clipboard would let me manually CTRL+V to Excel in the original format, but this failed. The original "copy" was of multiple columns of strings in a single rows of strings from Excel, and the manual "paste" of the individual formats back into excel kept all the strings into a single cell (with the exception of HTML Format that created multiple rows of data--also wrong). The different formats included CF_LOCALE (16), CF_TEXT (1), CF_OEMTEXT (7), CF_UNICODETEXT (13), AND HTML Format (49384).
So, still: no solution.
Edit2:
I realized that I could create strings in python with actual tabs pressed in between the string, instead of using \t, and it worked to create a single string that would place the data into different columns of a single row when pasted into Excel.
Also, I realized that if I CTRL+V directly into Excel (not on the Row heading), on the actual row in which I want to paste the data, I no longer get the Excel "warning message". So, using this work around might work. If no one has any input, then this simple approach might be good enough.
However, I would like to be able to simply click on the row heading instead of the first relevant row cell to paste the data without the Excel warning popup. Ideas are still welcome, and it would be best to have it all done via python (without modifications to Excel as the app may be run on different Windows OS PCs).
So: possible simple solution, but not perfect.
Edit3:
So I've worked out a solution based on Edit2. The Excel "warning" popup still happens if Excel is opened as an app on the working computer; however, if the Excel file is opened and editable via an online processor, then the user can highlight the row heading and paste without generating the Excel "warning" popup. This works in my specific case, although the better solution would be to have the copied data not generate the Excel "warning" popup in any situation. Regardless, if no one knows how to prevent the Excel warning popup through python alone, then I can still work with this method.
Here's my solution (note that the spaces in the long string are actually 'tabs'):
import pyperclip
# t variables are defined prior to the below code
# note: the " " parts in the data string are actually tabs
data = t1 + " " + t2 + " " + " " + t3 + " " + t4 + " " + t5 + " " + t6 + " " + t7 + " " + " " + "t8" + " " + " " + " " + " " + " " + " " + t9 + " " + t10 + " " + t11 + " " + t12 + " " + " " + " " + " " + " " + " " + t13
pyperclip.copy(data)
print("clipboard:", data)
# now manually pressing CTRL+V while inside Excel (online processor) will
# paste the various t variables in the appropriate cells designated by
# the " " tabs in between. Of note, this works for columns of a single
# row as I didn't need multiple rows of data for my task.
Below is code to create a 5 row by 3 column grid of Entries in tkinter. Pressing the copy button copies the content of the Entries as a tab / newline separated string to the clipboard which can then be pasted into excel.
import tkinter as tk
from tkinter import ttk
ROWS = 5
COLS = 3
root = tk.Tk()
rows = [] # Container for Entry widgets.
# Create and grid the Entry widgets.
for row in range( ROWS ):
temp = []
for col in range( COLS ):
temp.append( ttk.Entry(root, width = 10 ))
temp[-1].grid( row = row, column = col )
rows.append( temp )
def entries_to_lists( rows ):
list_out = []
for row in rows:
temp = []
for col in row:
temp.append( col.get() )
list_out.append( temp )
return list_out
def string_out( rows ):
""" Prepares a '\t', '\n' separated string to send to the clipboard. """
out = []
for row in rows:
out.append( '\t'.join( row )) # Use '\t' (tab) as column seperator.
return '\n'.join(out) # Use '\n' (newline) as row seperator.
def do_copy():
data = entries_to_lists( rows )
root.clipboard_clear()
root.clipboard_append( string_out( data )) # Paste string to the clipboard
root.update() # The string stays on the clipboard after the window is closed
ttk.Button( text = " Copy ", command= do_copy ).grid( column = 1 )
# Button to trigger the copy action.
root.title("Copy to Excel Test")
root.geometry("400x200+10+10")
root.mainloop()
This copied into Excel 2013 in Windows 10 with no warning messages.
string_out will generate a suitable string from any list of lists of strings, a 2d list.
I am trying to write a VBA code to read values and write it to where I want from 4 thousand different text files.
As an example the fine name is like NACA63220_1.30_17_CD.txt and NACA63220_1.05_12_CL.txt
In this name, the value 1.30 changes, 17 changes and CD becomes CL etc.
I want to create loops so that I read and paste the value I want from these files one by one.
Mach = Array ("0.2_", "0.6_", "0.9_", "1.05_", "1.30_")
Alpha = Array(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20)
Letter = Array("_CD", "_CL", "_CM")
strFile = D:\Database\NACA63220_ + Mach(5) + Alpha(18) + Letter(1) .txt
I want to have something like this with loops so that in this instance this strFile becomes D:\Database\NACA63220_ 1.30_17_CD.txt and then I can continue with my code.
You need to concatenate strings with & not + (which is for calculation only). Also your strings need to be enclosed in quotes "".
strFile = "D:\Database\NACA63220_" & Mach(5) & Alpha(18) & Letter(1) & ".txt"
Note that depending on how your arrays were defined the counting starts with zero 0 not with 1. So the last item is Mach(4) not Mach(5). In this case …
strFile = "D:\Database\NACA63220_" & Mach(4) & Alpha(17) & Letter(0) & ".txt"
should give the desired result D:\Database\NACA63220_ 1.30_17_CD.txt
This is driving me nuts. I want to generate a random number in excel but in the following format
+++522/7226/61416+++
So I need 3 blocks of numbers randomly generated
1ste block = RANDBETWEEN(0;999)
2nd block = RANDBETWEEN(0;9999)
3rd block = RANDBETWEEN(0;99999)
I know how RANDBETWEEN works but I can't to get it working with the +++ and the /
How using & and " " to include strings:
="+++"& TEXT(RANDBETWEEN(0;999);"000")&"/"&TEXT(RANDBETWEEN(0;9999);"0000")&"/"&TEXT(RANDBETWEEN(0;99999);"00000")&"+++"
Even more efficient is Ron's suggestion below:
=TEXT(RANDBETWEEN(1;999999999999);"+++000\/0000\/00000+++")
I found the article about putting excel cells into an email using the RangetoHTML function in VBA. It works like a charm, but now I’m facing a Problem.
If there are Umlaut (e.g.: ü, ä, ö) in the cells the result in the email shows strange symbols (e.g.: ä, …).
I looked up the written temp.htm file. On the first view of this file, it seems the umlaute are correctly written, but after looking through the file with an hex editor i found that the written symbols are not correct.
The function which writes the file is: PublishObjects.Add
So I hope someone can help me with this.
Edit: Added a testfile. Word and Office is needed.
Select the table and run the procedure SendMail.
You will always have problems with vba and foreign chars and the web.
EDIT:
Because you can't separate the cell values from the html the function below will unfortunately not work in this situation. BUT:
if you Save a copy of the document with western European windows encoding it will work.
(See comments below).
To be able to do that you press "Save As" and there is a dropdown on the left side of the save button (Tools) which will give you a dialog where you can change the encoding.
The image has ben lifted from technet and always save web.. is not necessary.
EOF EDIT:
This is a function I have used, Unfortunately can't remember who I got it from, But its from the olden days of vba and classic asp
Put your email cell formula into this function and it should work because all the letters are html encoded. Its slow and makes a bad overhead. But it will work.
Function HtmlEncode(ByVal inText As String) As String
Dim i As Integer
Dim sEnc As Integer
Dim repl As String
HtmlEncode = inText
For i = Len(HtmlEncode) To 1 Step -1
sEnc = Asc(Mid$(HtmlEncode, i, 1))
Select Case sEnc
Case 32
repl = " "
Case 34
repl = """
Case 38
repl = "&"
Case 60
repl = "<"
Case 62
repl = ">"
Case 32 To 127
'Numbers
Case Else
repl = "&#" & CStr(sEnc) & ";" 'Encode it all
End Select
If Len(repl) Then
HtmlEncode = Left$(HtmlEncode, i - 1) & repl & Mid$(HtmlEncode, i + 1)
repl = ""
End If
Next
End Function