MS Word: select text inside a table cell - ms-word

I need to select a text (for example, two chars) inside a cell in a table in a Word document. The following code:
Sub testTable()
For Each itable In ActiveDocument.Tables
itable.Cell(1, 2).Range.Select
Next
End Sub
selects all the content of the second cell in the first row of the table. How have I to modify it to select only a subset of the cell content, for example from the 4th char to the 9th char?

The Range object has a Characters property, so:
itable.Cell(1,2).Range.Characters(4).Select
Selection.MoveEnd wdCharacter, 5
Another way to go about it is to work with Range objects:
Dim rng as Word.Range
Set rng = itable.Cell(1,2).Range.Characters(4)
rng.End = itable.Cell(1,2).Range.Characters(9)
And there are variations on the theme...

Related

LibreOffice Calc Range Max and delete macro

I have a sheet in libreoffice Calc which has an Id Column with incremental value from 1 to N.
I need to create a Macro in VBA (linked to a button i will create later) where i can select the last ID (which is the MAX id also) and delete the entire row relating to this ID.
i tried this so far
Sub suppression
dim maxId as Integer
my_range = ThisComponent.Sheets(0).getCellRangebyName("B19:B1048576")
maxId = Application.WorksheetFunction.Max(range("Dépôts!B19:B1048576"))
MsgBox maxId
End Sub
Thanks a lot for your help.
In libreoffice BASIC you first need to get the data array of the cell range. This is an array of arrays each representing a row of the cell range. It is indexed from zero irrespective of the location of the cell range within the sheet. Because your cell range is one column wide, each member array has only one member, which is at index zero.
As Jim K says, 'Application.WorksheetFunction' is from VBA. It is possible to use worksheet functions in LibreOffice BASIC, but these act on ordinary arrays rather than cell arrays, and the MAX function takes a one-dimensional array so it would be necessary to first reshape the data array using a loop. Furthermore, if you want to delete the row corresponding to the maximum value you are then faced with the problem of finding the index of that row using only the value itself.
It is much simpler to find the index by looping over the data array as shown in the snippet below.
Also, rather than traversing over a million rows, it would save computational effort to obtain the last used row of the spreadsheet via the BASIC function 'GetLastUsedRow(oSheet as Object)', which is supplied with LibreOffice. This is located in the 'Tools' library in 'LibreOffice Macros & Dialogs'. To use it you have to put the statement: 'Globalscope.BasicLibraries.LoadLibrary("Tools")' somewhere before you call the function.
To delete the identified row, get the XTableRows interface of the spreadsheet and call its removeByIndex() function.
The following snippet assumes that the header row of your table is in row 18 of the sheet, as suggested by your example code, which is in row 17 when numbered from zero.
Sub suppression()
' Specify the position of the index range
''''''''''''''''''''''''''''''''''''
Dim nIndexColumn As Long '
nIndexColumn = 1 '
'
Dim nHeaderRow As Long '
nHeaderRow = 17 '
'
''''''''''''''''''''''''''''''''''''
Dim oSheet as Object
oSheet = ThisComponent.getSheets().getByIndex(0)
' Instead of .getCellRangebyName("B19:B1048576") use:
Globalscope.BasicLibraries.LoadLibrary("Tools")
Dim nLastUsedRow As Long
nLastUsedRow = GetLastUsedRow(oSheet)
Dim oCellRange As Object
' Left Top Right Bottom
oCellRange = oSheet.getCellRangeByPosition(nIndexColumn, nHeaderRow, nIndexColumn, nLastUsedRow)
' getDataArray() returns an array of arrays, each repressenting a row.
' It is indexed from zero, irrespective of where oCellRange is located
' in the sheet
Dim data() as Variant
data = oCellRange.getDataArray()
Dim max as Double
max = data(1)(0)
' First ID number is in row 1 (row 0 contains the header).
Dim rowOfMaxInArray As Long
rowOfMaxInArray = 1
Dim i As Long, x As Double
For i = 2 To UBound(data)
x = data(i)(0)
If x > max Then
max = x
rowOfMaxInArray = i
End If
Next i
' if nHeaderRow = 0, i.e. the first row in the sheet, you could save a
' couple of lines by leaving the next statement out
Dim rowOfMaxInSheet As long
rowOfMaxInSheet = rowOfMaxInArray + nHeaderRow
oSheet.getRows().removeByIndex(rowOfMaxInSheet, 1)
End Sub

(Matlab) How to check if cell array contains string

I am trying to grab data from an excel spread sheet and grab only the information from cells that match a string. Eg. if cell A10 contains the word 'Canada' it should return that cell.
I have tried using strcmp(https://www.mathworks.com/help/matlab/ref/strcmp.html) to check if string in argument 1 is contained in a cell array containing many strings, the second argument
[num,txt,raw] = xlsread('\\Client\C$\Users\Fish\Desktop\dataset\dataset.csv');
mytable = cell(raw);
for i = 1:54841
array_index = i;
string_index = mytable(i,2);
string_eastern = {'Canada', 'Ontario'};
if strcmp(string_index,string_eastern);
fprintf('%d\n',array_index)
end
end
In the above example if my string_eastern only contains one element, say 'Canada', it will return the index value of every instance of 'Canada'. If I add more elements I expect it would return index values for every instance where string_index would match with a string contained in string_eastern. However I get no results at all if I add more elements.
Pretty much I wanted to check my string_index agaisnt string_eastern, if the values match then I want it to return that cell value. This works when string_eastern is only 1 element but does not work with more than 1.
To access cell contents, use the curly brackets {}. So if I wanted to access the first element of my cell, I would say this:
string = cell{1};
Read more on the MATLAB Documentation about cells to learn more and to answer any of your further questions.

how to set paragraph column counts using MS Word

I just want to set the last para columns in below code:
wordDoc.Paragraphs.Last.Range.PageSetup.TextColumns.SetCount(3);
But it sets the page 3 columns;
So, what code can set the last para columns?
There is no such thing as a paragraph columns property - only a page columns property (TextColumns). If you want to limit the scope of TextColumns, insert a Section break before (and after, if applicable), the paragraph concerned. For example:
Sub Demo()
Dim wordDoc As Document
Set wordDoc = ActiveDocument
With wordDoc.Paragraphs.Last.Range
.InsertBreak Type:=wdSectionBreakContinuous
.PageSetup.TextColumns.SetCount (3)
End With
End Sub

Need help looping Macro that cut/inserts and deletes a cell range based on a selected row

This Macro is used to cut, insert and delete a cell range section of a workbook.
The problem I was trying to solve and gave up with the lack of response in another thread is why copying multiple non-adjacent rows to the MS clipboard often loses their row line-breaks when pasting.
E.g. Since trying to paste 3 non-adjacent rows into row 10, 11 and 12, often puts all 3 rows into row 10 with one row in fields A10-P10, the next row in Q10-AF10 and the last row into AG10-AV10...
I edited the Macro below to fix this mistake when this happens.
So, for example, I can now highlight row 10 and run the macro to cut/insert the fields Q10-AF10 to A11-P11 and delete/shift left the blank fields now in Q10-AF10.
I'm hoping for help to loop this process until there's no data outside Column A-P. In this case, no data outside cell P10.
Sub FixAllOnLine1OneRowAtATimeInsertToNextRow()
Application.ScreenUpdating = False
Dim copySheet As Worksheet
Dim pasteSheet As Worksheet
Set copySheet = ActiveSheet
Set pasteSheet = ActiveSheet
copySheet.Range("Q" & ActiveCell.Row & ":AF" & ActiveCell.Row).Copy
Range("Q" & ActiveCell.Row & ":AF" & ActiveCell.Row).Offset(1).Select
pasteSheet.Cells(ActiveCell.Row, 1).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
Application.CutCopyMode = False
Application.ScreenUpdating = True
Columns("Q:AF").Select
Selection.Delete Shift:=xlToLeft
End Sub
Ok, I made some headway. I just have one super easy issue and then I need to loop it.
The first issue is that it cuts Column Q:AF correct of the row I've highlighted and shifts the entire Column Q:AF to the left, but it INSERTS the cut cells into the fixed range, A2:P2. I want to INSERT the cut cells down ONE row from my selection. I KNOW this is a couple characters in the Offset, I just can't get it.
Then, once it's working properly...say I highlight row 10, it cuts Q10:AF10 and instead INSERTS the cells into A11:P11 and shifts "Q:AF" to the left, then I need to figure out how to get it to loop until there's no more data to right of Column P. When this problem occurs pasting multiple rows from the clipboard all into the first row losing the row line-breaks, it's always quite a few rows.
Any ideas?
Thanks so much!
Mark
Sub FixAllOnLine1OneRowAtATimeInsertToNextRow()
Dim ws As Worksheet
Dim lNextRow As Long
Application.ScreenUpdating = False
Set ws = ActiveSheet
ws.Range("Q" & ActiveCell.Row & ":AF" & ActiveCell.Row).Copy 'Copy the row of the selected cell from Q:AF
ws.Range("Q" & ActiveCell.Row & ":AF" & ActiveCell.Row).Offset(1).Select 'Select the cells you have just copied. Not needed
ws.Cells(ActiveCell.Row, 1).End(xlUp).Offset(1, 0).Insert xlShiftDown ' Paste the copied values in to column "A" on next row?
'lNextRow = ws.Range("A" & Rows.count).End(xlUp).Row + 1 'Get Next Row number
'Range("A" & lNextRow).PasteSpecial xlPasteValues
Application.CutCopyMode = False
Range("Q:AF").Delete Shift:=xlToLeft
'Columns("Q:AF").Select
'Selection.Delete Shift:=xlToLeft
Application.ScreenUpdating = True
ActiveCell.Offset(RowOffset:=-1, columnOffset:=0).Activate 'Added to move active cell up one row to run it again for multiple groups to apply fix.
End Sub
Here's a solution in another direction just in case someone from the engines needs it...
Sub ReduceNoOfColumns()
Dim iRow As Integer 'Row to be manipulated
Dim iRowToPasteTo 'Row number to paste the copied cells
Dim iCurCol As Integer 'Current Column number of first cell with a value to cut
Dim NoOfCols As Integer 'integer to hold max number of columns
Dim sAddress As String
iRow = ActiveCell.Row
iRowToPasteTo = iRow + 1
NoOfCols = 16 'Set this number to the total number of columns you wish to have (in your case 16)
iCurCol = NoOfCols + 1
Do Until Cells(iRow, iCurCol).Value = "" 'Keep looping until we get to an empty column
sAddress = ColNoToLetter(iCurCol) & iRow & ":" & ColNoToLetter(iCurCol + NoOfCols - 1) & iRow
Rows(iRowToPasteTo & ":" & iRowToPasteTo).Insert Shift:=xlDown
Range(sAddress).Copy
Range("A" & iRowToPasteTo).PasteSpecial xlPasteAll
Range(sAddress).Clear
iCurCol = iCurCol + NoOfCols
iRowToPasteTo = iRowToPasteTo + 1
Loop
End Sub
Function ColNoToLetter(iCol As Integer) As String
Dim vArr
vArr = Split(Cells(1, iCol).Address(True, False), "$")
ColNoToLetter = vArr(0)
End Function

maskedEditColumn datagridview how to use class? is it what i need?

I am trying to mask user's input in a datagridview column and i found this ready class Masked edit column Class that adds a 'mask edit column' option in the column types list. When i select this column type a mask field is being added in the list of column properties. I tried to do my job by adding some mask elements in this 'Mask' field, but when I run the code it didnt restrict me from adding other characters. I re-opened the 'edit columns menu' and I saw that the 'Mask' field was empty.
I want the text cell to accept 20 chars maximum and only: 1.Capital Letters(English & Greek), 2.these three chars(.,-), 3.Numbers 0-9
So as a first test i used only this mask(>????????????????????) but it didnt work as it didnt convert my characters to Uppercase and accepted more than 20 chars when i end the cell edit.
i am not sure the way to go is the Masked Text Box way. i have made many projects on vb and i used to use a loop in the textChanged event of a text box to restrict characters entry. the loop is this : (but i cant use it now in the valueChanged event cause it seems that 'value' doesn't have a selectionStart property.)
Dim charactersDisallowed As String = "!##$%^&*()+=|}{][:;?/><.,~""
Dim theText As String = txtCopies.Text
Dim Letter As String
Dim SelectionIndex As Integer = txtCopies.SelectionStart
Dim Change As Integer
For x As Integer = 0 To txtCopies.Text.Length - 1
Letter = txtCopies.Text.Substring(x, 1)
If charactersDisallowed.Contains(Letter) Then
theText = theText.Replace(Letter, String.Empty)
Change = 1
End If
Next
txtCopies.Text = theText
txtCopies.Select(SelectionIndex - Change, 0)
So,
Is a masked text cell what i need? and if yes( Why is this mask box not keeping the mask i enter? And how can i use this class to do my job?)
What can i alternately do to restrict some characters in a column's cells? (I will then convert to Uppercase on cellEndEdit)
I finally did it by removing the unwanted characters on cellvaluechanged event, which seems that is being raised when I end the cell's edit by for example hitting "Enter".