I have a word template that has a variable number of occurrences of the "SEQ" field "testnum" tag (depending on how much information needs to be included - minumum 1 SEQ field, no maximum.) I would like to create a section at the top that calculates how often SEQ appears in the document, and displays a total. To make the template easy to maintain for others, I would like to use the F9 function key to enter the solution, instead of having it in vba.
Ideally, it would be possible to count by the tag occurrence, without creating additional bookmarks, but I am opent to any solutions. Thank you!
When you record a Macro in Word you can press the Keyboard button to assign a keyboard shortcut to it. I wouldn't use F9 though as it is extremely useful. (When you press the keyboard-combination Word will show which command, if any, it is currently assigned to.)
Here is some code you can study/explore:
Sub CheckSEQs()
Dim fld As Field
Dim iTotal As Integer
iTotal = 0
For Each fld In ActiveDocument.Fields
'Debug.Print fld.Code
If InStr(fld.Code, "SEQ") > 0 Then
'search for "testnum" as well
iTotal = iTotal + 1
End If
Next fld
MsgBox "There are " & iTotal & " SEQ fields."
End Sub
Related
I have a very long list of words like this in the Atom editor
car
cat
dog
town
I would like to convert this with Atom into an array like this:
['car', 'cat', 'dog', 'town']
It is easy to create a ' on the left of all words by putting the cursor left to car and then pressing alt+shitf+arrow_down till one reaches town and then pressing '. For the right, the best thing I found is to to click at the end of each word with the mouse and pressing control till all cursors are set. Then just add ', and backspace. This gives me
'car', 'cat', 'dog', 'town'
but its very cumbersome for a very long list. Is there a better method to this task in Atom?
Use the find & replace function with the regex option.
Replace new lines \n with ',', for example.
In a just-downloaded Atom, I was able to use the following sequence.
The "Split Into Lines" does not appear to have a default keybinding, although once setup it would be possible to perform the (somewhat long) sequence of steps sans-Menu.
Ctrl+A - selects all
Menu -> Selection -> Split Into Lines
Home - moves all cursors to the start/end of each line and wrap
'
End
',Space
Delete - collapses lines
Home - change back to single-cursor mode and select entire line
Shift-End
[ - this auto-bracketed the selected text "['car', ..., 'town', ]"
End - now tidy up the the ", " before the end "]"
Left-Arrow
Backspace
Backspace
Not quite as short as a regex-replace.. adapt and/or take concepts as useful. Multi-cursor mode is incredibly powerful in certain cases.
I am desiging dataentryform in access . I made tables and the datatye of one field is Date/time but in property field in format I put mm.\yyyy to get month and year . how should I define input mask for it? I want to see --.----
when I enter data in form I can see calender beside this field but I have to choose day as well I dont want to choose day however the day that I chose doesnt save in table but I have to choose day aw well.
more explaination: I have 2 fields that should define as mm.yyyy .one field is (start of project example 01.2010) and the next field is end of project which also has the same format mm.yyyy (03.2015).
and later I want to get a query which shows duration of project ( end of project - start of project) . so I should also do calculation according to my data.
but I dont know what kind of data type should I define in the table for these two fields. at first I tried Date/Time . but I couldnt find suitable format. then I changed it to short text and I entered 00.0000 in input mask.
what is the best solution because I have to calculate duration of project according to these two fields later? (in queries)
There are many ways around this. One is simply to allow the user to type freely in an unbound textbox, then validate/correct before updating.
Another is to have two/three juxtaposed textboxes for year-month(-day), then build the date value with DateSerial(y, m, d).
in VBA, mm/yyyy alone can never form a date value, so must silently add a day somehow.
Input masks should be avoided as they are a prime hate object for users.
If you insist, you can get an idea how to handle this from my article:
Entering ISO formatted date with input mask and full validation in Microsoft Access
It assumes the ISO sequence because year-month determines the possible day values.
Addendum:
Though decimal months is not an exact measure due to the varying day counts of the months, you will get pretty close with this function:
Public Function DecimalMonths( _
ByVal Date1 As Date, _
ByVal Date2 As Date) _
As Double
Dim Part1 As Double
Dim Part2 As Double
Dim Months As Double
Dim Days1 As Integer
Dim Days2 As Integer
Days1 = Day(DateSerial(Year(Date1), Month(Date1) + 1, 0))
Days2 = Day(DateSerial(Year(Date2), Month(Date2) + 1, 0))
Months = DateDiff("m", Date1, Date2)
Part1 = (Day(Date1) - 1) / Days1
Part2 = (Day(Date2) - 1) / Days2
Months = Months - Part1 + Part2
DecimalMonths = Months
End Function
Please note, that the count from 2017-04-15 to 2017-06-01 is 1.53
while it would be 1.5 from 2017-04-16 to 2017-06-01.
I have 16 items named q1,q2,q3,...,q16 and txt_q1,txt_q2,...,txt_q16
And I need to check each one, so I have a for and inside I have the If like this:
For Cnt AS Integer = 1 To 16 Step 1
If("q"&cnt = "") Then
"txt_q"&cnt.Style.Add("color","blue")
....
..
End If
End For
The idea is check al items with a For to avoid the 16 Ifs, but I have a syntax error.
What can I do?
the txt_q1,txt_q2... are IDs for asp:labels, and I have a radiobuttonList, so I get the radiobutton text and I set q1, q2, q3... to the corresponding radiobuttonlist. So I want to check if there is a radiobuttonlist that is not checked, if not I change the color to blue to the asp:label. So I want to avoid making 16 ifs for each radiobuttonlist and make it with a For, because the only thing that change in the variables is the number is the same "q" and the same "txt_q" so I want to add the number to "q" or "txt_q" to make it one variable called q1 or txt_q1 that already exist and that way acces to the txt_q1.Style.Add() and change the color of that label.
Thank You
Just for your understanding:
When you write "txt_q"&cnt, you are creating a new string literal which holds e.g. "txt_q1", "txt_q2", etc. This resembles the name of the variables, but is really something completely different. The name of the variable is just for you to write in code. The value of the variable is a reference to the control object. What you need is to obtain the reference to the controls. This can be done on several ways, one is to use the FindControl() method.
For Cnt AS Integer = 1 To 16 Step 1
Dim c = FindControl("q" & cnt) 'pass in the ID here, you will get a reference
'you can use c to access the properties e.g. c.Style
End For
Again, just to clarify
c.Style 'c is a variable holding a reference to the control
"c".Style ' "c" is a simple string
I am writing a simple GUI in AutoHotkey, one of the elements is the ability to associate a number with a button label:
Call:
{
book := {"Tel Maison": 8912, "Tel Mobile": 000000}
nr := book[%A_GuiControl%]
MsgBox %A_GuiControl% - number: %nr%
}
CapsLock::
Gui, Add, Button, gCall, Tel Maison
Gui, Add, Button, gCall, Tel Mobile
Gui, Show
When running this script I get, upon pressing a button, an error message (The following variable name contains an illegal caracter: "Tel Maison") pointing to
nr := book[%A_GuiControl%]
I believe that this is due to the space character in the label name.
Q1: isn't it possible to use hash keys with a space?
I modified the script to
Call:
{
book := {"TelMaison": 8912, "TelMobile": 000000}
nr := book[%A_GuiControl%]
MsgBox %A_GuiControl% - number: %nr%
}
CapsLock::
Gui, Add, Button, gCall, TelMaison
Gui, Add, Button, gCall, TelMobile
Gui, Show
It now runs but the variable nr is empty.
Q2: The label is passed via A_GuiControl as a string, right? If so why isn't there a match for the key in the example above?
I also tried to use book := {TelMaison: 8912, TelMobile: 000000} but the result is the same
This is a typical example of expressions vs. string literals in AHK, which can be troublesome in some cases. In order to use variable contents as a key for an object, simply put the variable in the brackets and don't enclose them in percentage signs (%):
nr := book[A_GuiControl]
This way, you can very well use spaces for the button names.
What's the problem with book[%A_GuiControl%]?
AHK expects either a hard-coded string (e.g. book["Tel Maison"]) or a variable when you access an object property by key. Since we don't pass it a hard string, it's assuming that TelMaison or Tel Maison is the variable name. Accessing Tel Maison will directly lead to a runtime error, since variable names can't have spaces. TelMaison is legal, but contains nothing. So basically, we access the object with an empty string as the key (like book[""]). This, by the way, isn't illegal and you could in fact use the empty string as a key, although I think that's not reasonable in most cases.
Why does AHK offer this weird syntax then?
There are scenarios in which you might want to use the contents of a variable in turn as a variable name. Look at this example for instance:
TelMaison := 8912
TelMobile := 0
Gui, Add, Button, gCall, TelMaison
Gui, Add, Button, gCall, TelMobile
Gui, Show
Exit
Call:
nr := %A_GuiControl%
msgbox % nr
return
With nr := %A_GuiControl%, nr is assigned the value of the variable, whose name is equal to the contents of A_GuiControl. I wouldn't recommend this pattern though, since it's very error-prone and simply bad design.
So I have an ASP.Net (vb.net) application. It has a textbox and the user is pasting text from Microsoft Word into it. So things like the long dash (charcode 150) are coming through as input. Other examples would be the smart quotes or accented characters. In my app I'm encoding them in xml and passing that to the database as an xml parameter to a sql stored procedure. It gets inserted in the database just as the user entered it.
The problem is the app that reads this data doesn't like these characters. So I need to translate them into the lower ascii (7bit I think) character set. How do I do that? How do I determine what encoding they are in so I can do something like the following. And would just requesting the ASCII equivalent translate them intelligently or do I have to write some code for that?
Also maybe it might be easier to solve this problem in the web page to begin with. When you copy the selection of characters from Word it puts several formats in the clipboard. The straight text one is the one I want. Is there a way to have the html textbox get that text when the user pastes into it? Do I have to set the encoding of the web page somehow?
System.Text.Encoding.ASCII.GetString(System.Text.Encoding.GetEncoding(1251).GetBytes(text))
Code from the app that encodes the input into xml:
Protected Function RequestStringItem( _
ByVal strName As System.String) As System.String
Dim strValue As System.String
strValue = Me.Request.Item(strName)
If Not (strValue Is Nothing) Then
RequestStringItem = strValue.Trim()
Else
RequestStringItem = ""
End If
End Function
' I get the input from the textboxes into an array like this
m_arrInsertDesc(intIndex) = RequestStringItem("txtInsertDesc" & strValue)
m_arrInsertFolder(intIndex) = RequestInt32Item("cboInsertFolder" & strValue)
' create xml file for inserts
strmInsertList = New System.IO.MemoryStream()
wrtInsertList = New System.Xml.XmlTextWriter(strmInsertList, System.Text.Encoding.Unicode)
' start document and add root element
wrtInsertList.WriteStartDocument()
wrtInsertList.WriteStartElement("Root")
' cycle through inserts
For intIndex = 0 To m_intInsertCount - 1
' if there is an insert description
If m_arrInsertDesc(intIndex).Length > 0 Then
' if the insert description is of the appropriate length
If m_arrInsertDesc(intIndex).Length <= 96 Then
' add element to xml
wrtInsertList.WriteStartElement("Insert")
wrtInsertList.WriteAttributeString("insertdesc", m_arrInsertDesc(intIndex))
wrtInsertList.WriteAttributeString("insertfolder", m_arrInsertFolder(intIndex).ToString())
wrtInsertList.WriteEndElement()
' if insert description is too long
Else
m_strError = "ERROR: INSERT DESCRIPTION TOO LONG"
Exit Function
End If
End If
Next
' close root element and document
wrtInsertList.WriteEndElement()
wrtInsertList.WriteEndDocument()
wrtInsertList.Close()
' when I add the xml as a parameter to the stored procedure I do this
cmdAddRequest.Parameters.Add("#insert_list", OdbcType.NText).Value = System.Text.Encoding.Unicode.GetString(strmInsertList.ToArray())
How big is the range of these input characters? 256? (each char fits into a single byte). If that's true, it wouldn't be hard to implement a 256 value lookup table. I haven't toyed with BASIC in years, but basically you'd DIM an array of 256 bytes and fill in the array with translated values, i.e. the 'a'th byte would get 'a' (since it's OK as is) but the 150'th byte would get a hyphen.
This seems to work for long dash to short dash and smart quotes to regular quotes. As my html pages has the following as the content type. But it converts all the accented characters to questions marks. Which is not what the Text version of the clipboard has. So I'm closer, I just think I have the target encoding wrong.
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
System.Text.Encoding.ASCII.GetString(System.Text.Encoding.GetEncoding("iso-8859-1").GetBytes(m_arrFolderDesc(intIndex)))
Edit: Found the correct target encoding for my purposes which is 1252.
System.Text.Encoding.GetEncoding(1252).GetString(System.Text.Encoding.GetEncoding("iso-8859-1").GetBytes(m_arrFolderDesc(intIndex)))
If you convert to a non-unicode character set, you will lose some characters in the process. If the legacy app reading the data doesn't need to do any string transformations, you might want to consider using UTF-7, and converting it back once it gets back into the unicode world - this will preserve all special characters.