问:
VBA - Custom Function to close work book - not working
I am trying to write a simple function (in a module FileIO) which would take an instance of a work book, and just close it. This function is invoked from another module Business.
Below is the code snippet.

```<code>Public Function CloseExcelFile(wkBook As Workbook)
    If (wkBook Is Not Nothing) Then
        wkBook.Save
        wkBook.Close
    End If
End Function
</code>```

I invoke this method by using the command FileIO.CloseExcelFile(catWorkBook). Variable catWorkBook is the object reference to the workbook I created (in a step before).

When ever I try too invoke the custom function, I am getting the error

object does not support this method or property

The below command closes the work book with no errors.

```<code>catWorkBook.Close
</code>```

But the same does not happen when I use the custom function. What is going wrong here?

答:
As braX pointed out, your Not isn't in the right place.

You also don't need a Function here. Change it to a Sub. In fact, you barely need the Sub when you reduce it to one line like this:

```<code>Public Sub CloseExcelFile(wkBook As Workbook)
    If Not wkBook Is Nothing Then wkBook.Close(SaveChanges:=True)
End Sub
</code>```

Body:
I am trying to write a simple function (in a module FileIO) which would take an instance of a work book, and just close it. This function is invoked from another module Business.
Below is the code snippet.

Public Function CloseExcelFile(wkBook As Workbook)
    If (wkBook Is Not Nothing) Then
        wkBook.Save
        wkBook.Close
    End If
End Function

I invoke this method by using the command FileIO.CloseExcelFile(catWorkBook). Variable catWorkBook is the object reference to the workbook I created (in a step before).

When ever I try too invoke the custom function, I am getting the error

object does not support this method or property

The below command closes the work book with no errors.

catWorkBook.Close

But the same does not happen when I use the custom function. What is going wrong here?

Body:
As braX pointed out, your Not isn't in the right place.

You also don't need a Function here. Change it to a Sub. In fact, you barely need the Sub when you reduce it to one line like this:

Public Sub CloseExcelFile(wkBook As Workbook)
    If Not wkBook Is Nothing Then wkBook.Close(SaveChanges:=True)
End Sub


来源: stackexchange

问:
Finding location in list,
In Linq Get items higher then lastname I asked how to get people higher then a certain name.

However we use a datagrid with paging and when showing only people higher then lastname "Jan", there's no way to get back to people starting with AA.

So I was searching for a way to find out on what location the person would have been if following the normal order of selection?

hope this makes sense :)

[edit]
The query type is of EntityQuery.
[/edit]

答:
So you want the index of first person record that matches your condition?

```<code>var index = query.TakeWhile(person => person.LastName.CompareTo(name) < 0).Count();
</code>```

This counts the number of elements that match the condition and the returned value is the index of the first element that does not match with the condition.

Just note that you must negate the condition that you used with Where() as in this case TakeWhile() is used to get the items that you don't want.

ContentLicense: CC BY-SA 2.5

Title: Finding location in list,

Body:
So you want the index of first person record that matches your condition?

var index = query.TakeWhile(person => person.LastName.CompareTo(name) < 0).Count();

This counts the number of elements that match the condition and the returned value is the index of the first element that does not match with the condition.

Just note that you must negate the condition that you used with Where() as in this case TakeWhile() is used to get the items that you don't want.


问:
Printing certain values using Collections.frequency()
I have an array as follows:

```<code>int[] array = {11, 14, 17, 11, 48, 33, 29, 11, 17, 22, 11, 48, 18};
</code>```

What I wanted to do was to find the duplicate values, and print them.

So my way of doing this was to convert to ArrayList, then to Set and use a stream on the Set.

```<code>ArrayList<Integer> list = new ArrayList<>(array.length);
for (int i = 0; i < array.length; i++) {
    list.add(array[i]);
}

Set<Integer> dup = new HashSet<>(list);
</code>```

I then used a stream to loop through it and print the values using Collections.frequency.

```<code>dup.stream().forEach((key) -> {
            System.out.println(key + ": " + Collections.frequency(list, key));
        });
</code>```

Which will of course print them all, even if the count is one.

I thought adding in if(key > 1) but it's the value I want not the key.

How can I get the value in this instance to print only where value > 2.

I could probably put in:

```<code>int check = Collections.frequency(list, key);
            if (check > 1) {
</code>```

but this then duplicates Collections.frequency(list, key) in the stream and is quite ugly.

答:
```<code>package various;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

public class Frequency {
    public static void main(String[] args) {
        int[] array = {11, 14, 17, 11, 48, 33, 29, 11, 17, 22, 11, 48, 18};
        ArrayList<Integer> list = new ArrayList<>(array.length);
        for (int i = 0; i < array.length; i++) {
            list.add(array[i]);
        }

        Set<Integer> dup = new HashSet<>(list);

        dup.stream().forEach((key) -> {
            System.out.print((Collections.frequency(list, key) > 2) ? key + ": " + Collections.frequency(list, key) +"\n" : "");
        });
    }
}
</code>```

Output:

```<code>11: 4
</code>```

ContentLicense: CC BY-SA 3.0

Body:
I have an array as follows:

int[] array = {11, 14, 17, 11, 48, 33, 29, 11, 17, 22, 11, 48, 18};

What I wanted to do was to find the duplicate values, and print them.

So my way of doing this was to convert to ArrayList, then to Set and use a stream on the Set.

ArrayList<Integer> list = new ArrayList<>(array.length);
for (int i = 0; i < array.length; i++) {
    list.add(array[i]);
}

Set<Integer> dup = new HashSet<>(list);

I then used a stream to loop through it and print the values using Collections.frequency.

dup.stream().forEach((key) -> {
            System.out.println(key + ": " + Collections.frequency(list, key));
        });

Which will of course print them all, even if the count is one.

I thought adding in if(key > 1) but it's the value I want not the key.

How can I get the value in this instance to print only where value > 2.

I could probably put in:

int check = Collections.frequency(list, key);
            if (check > 1) {

but this then duplicates Collections.frequency(list, key) in the stream and is quite ugly.

Body:
package various;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

public class Frequency {
    public static void main(String[] args) {
        int[] array = {11, 14, 17, 11, 48, 33, 29, 11, 17, 22, 11, 48, 18};
        ArrayList<Integer> list = new ArrayList<>(array.length);
        for (int i = 0; i < array.length; i++) {
            list.add(array[i]);
        }

        Set<Integer> dup = new HashSet<>(list);

        dup.stream().forEach((key) -> {
            System.out.print((Collections.frequency(list, key) > 2) ? key + ": " + Collections.frequency(list, key) +"\n" : "");
        });
    }
}

Output:

11: 4


问:
How do I apply an Ansible with_items loop to the included tasks?
The documentation for import_tasks mentions

Any loops, conditionals and most other keywords will be applied to the included tasks, not to this statement itself.

This is exactly what I want. Unfortunately, when I attempt to make import_tasks work with a loop

```<code>- import_tasks: msg.yml
  with_items:
    - 1
    - 2
    - 3
</code>```

I get the message

ERROR! You cannot use loops on 'import_tasks' statements. You should use 'include_tasks' instead.

I don't want the include_tasks behaviour, as this applies the loop to the included file, and duplicates the tasks. I specifically want to run the first task for each loop variable (as one task with the standard with_items output), then the second, and so on. How can I get this behaviour?

Specifically, consider the following:

Suppose I have the following files:

playbook.yml

```<code>---

- hosts: 192.168.33.100
  gather_facts: no
  tasks:
  - include_tasks: msg.yml
    with_items:
      - 1
      - 2
</code>```

msg.yml

```<code>---

- name: Message 1
  debug:
    msg: "Message 1: {{ item }}"

- name: Message 2
  debug:
    msg: "Message 2: {{ item }}"
</code>```

I would like the printed messages to be

Message 1: 1

  Message 1: 2

  Message 2: 1

  Message 2: 2

However, with import_tasks I get an error, and with include_tasks I get

Message 1: 1

  Message 2: 1

  Message 1: 2

  Message 2: 2

答:
You can add a with_items loop taking a list to every task in the imported file, and call import_tasks with a variable which you pass to the inner with_items loop. This moves the handling of the loops to the imported file, and requires duplication of the loop on all tasks.

Given your example, this would change the files to:

playbook.yml

```<code>---

- hosts: 192.168.33.100
  gather_facts: no
  tasks:
  - import_tasks: msg.yml
    vars:
      messages:
        - 1
        - 2
</code>```

msg.yml

```<code>---

- name: Message 1
  debug:
    msg: "Message 1: {{ item }}"
  with_items:
    - "{{ messages }}"

- name: Message 2
  debug:
    msg: "Message 2: {{ item }}"
  with_items:
    - "{{ messages }}"
</code>```

Body:
The documentation for import_tasks mentions

Any loops, conditionals and most other keywords will be applied to the included tasks, not to this statement itself.

This is exactly what I want. Unfortunately, when I attempt to make import_tasks work with a loop

- import_tasks: msg.yml
  with_items:
    - 1
    - 2
    - 3

I get the message

ERROR! You cannot use loops on 'import_tasks' statements. You should use 'include_tasks' instead.

I don't want the include_tasks behaviour, as this applies the loop to the included file, and duplicates the tasks. I specifically want to run the first task for each loop variable (as one task with the standard with_items output), then the second, and so on. How can I get this behaviour?

Specifically, consider the following:

Suppose I have the following files:

playbook.yml

---

- hosts: 192.168.33.100
  gather_facts: no
  tasks:
  - include_tasks: msg.yml
    with_items:
      - 1
      - 2

msg.yml

---

- name: Message 1
  debug:
    msg: "Message 1: {{ item }}"

- name: Message 2
  debug:
    msg: "Message 2: {{ item }}"

I would like the printed messages to be

Message 1: 1

  Message 1: 2

  Message 2: 1

  Message 2: 2

However, with import_tasks I get an error, and with include_tasks I get

Message 1: 1

  Message 2: 1

  Message 1: 2

  Message 2: 2

Body:
You can add a with_items loop taking a list to every task in the imported file, and call import_tasks with a variable which you pass to the inner with_items loop. This moves the handling of the loops to the imported file, and requires duplication of the loop on all tasks.

Given your example, this would change the files to:

playbook.yml

---

- hosts: 192.168.33.100
  gather_facts: no
  tasks:
  - import_tasks: msg.yml
    vars:
      messages:
        - 1
        - 2

msg.yml

---

- name: Message 1
  debug:
    msg: "Message 1: {{ item }}"
  with_items:
    - "{{ messages }}"

- name: Message 2
  debug:
    msg: "Message 2: {{ item }}"
  with_items:
    - "{{ messages }}"


问:
Sorting of ArrayList using Comparator in Java
I am having an issue with sorting an ArrayList with Ascending order.I am using Comparator and Collator Of Collection class .How can I achieve expected sorting order ? Help is much appreciated.

Ascending order calculated by Algorithm is :

```<code>[AutomationRejectNotification|,AutomationRejectNotification1011, AutomationRejectNotification1021,AutomationTestNotification1, AutomationTestNotification100,AutomationTestNotification2,testDisplay Template, Testing Chrome, Testing Field, Test Notfication, testnotif, Test Notification #1]
</code>```

Expected Ascending Sorting order is:

```<code>[AutomationRejectNotification1011, AutomationRejectNotification1021, AutomationRejectNotification|,AutomationTestNotification1, AutomationTestNotification2,AutomationTestNotification100,Test Notfication, Test Notification #1, testDisplay Template, Testing Chrome, Testing Field, testnotif]
</code>```

Java code:

```<code>public static void listSort(List<String> o1, boolean order) {
        final Pattern p = Pattern.compile("^\\d+");
        Comparator<String> c = new Comparator<String>() {
            public int compare(String object1, String object2) {
                Collator collator = Collator.getInstance(Locale.US);
                Matcher m = p.matcher(object1);

                if (!m.find()) {
                    return collator.compare(object1, object2);
                } else {
                    Long number2 = null;
                    Long number1 = Long.parseLong(m.group());

                    m = p.matcher(object2);
                    if (!m.find()) {
                        return collator.compare(object1, object2);
                    } else {

                        number2 = Long.parseLong(m.group());

                        int comparison = number1.compareTo(number2);
                        if (comparison != 0) {
                            return comparison;
                        } else {
                            return collator.compare(object1, object2);
                        }
                    }
                }

            }
        };
        o1.sort(c);
</code>```

答:
Your Comparator does not properly implement the contract of the Comparator interface, so all bets are off.  The compare() method must have all of these properties:

sgn(compare(x, y)) == -sgn(compare(y, x)) for all x and y.

((compare(x, y)>0) && (compare(y, z)>0)) implies compare(x, z)>0.

compare(x, y)==0 implies that sgn(compare(x, z))==sgn(compare(y, z)) for all z.

(API docs)

When both strings being compared contain a non-empty decimal digit sequence, you compare only by the numbers, whereas if at least one string is without any digits then you compare via the collator.  That produces these results:

```<code>compare("z1", "y") > 0

compare("y", "x3") > 0

compare("z1", "x3") < 0
</code>```

, which do not conform to the second required property (transitivity).

Possibly what you want to do is is compare the longest leading digitless substrings as a first criterion, breaking any ties by comparing the trailing numbers, if any.  That might look like this:

```<code>public static void listSort(List<String> o1, boolean order) {
    final Pattern p = Pattern.compile("([^0-9]*)([0-9]+)?");
    final Collator collator = Collator.getInstance(Locale.US);
    Comparator<String> c = new Comparator<String>() {
        public int compare(String object1, String object2) {
            Matcher m1 = p.matcher(object1);
            Matcher m2 = p.matcher(object2);

            if (!m1.lookingAt() || !m2.lookingAt()) {
                assert false : "Should never happen";
            }

            int result = collator.compare(m1.group(1), m2.group(1));

            if (result == 0) {
                String digits1 = m1.group(2);
                String digits2 = m2.group(2);

                if (digits1 != null && digits2 != null) {
                    Long number1 = Long.valueOf(digits1);
                    Long number2 = Long.valueOf(digits2);
                    result = number1.compareTo(number2);
                } else if (digits1 != null) {
                    result = 1;
                } else if (digits2 != null) {
                    result = -1;
                }
            }

            return result;
        }
    };
    o1.sort(c);
}
</code>```

That would be consistent with the expected order you presented, but there are other ordering schemes that would also produce the same result for those particular elements.

Body:
I am having an issue with sorting an ArrayList with Ascending order.I am using Comparator and Collator Of Collection class .How can I achieve expected sorting order ? Help is much appreciated.

Ascending order calculated by Algorithm is :

[AutomationRejectNotification|,AutomationRejectNotification1011, AutomationRejectNotification1021,AutomationTestNotification1, AutomationTestNotification100,AutomationTestNotification2,testDisplay Template, Testing Chrome, Testing Field, Test Notfication, testnotif, Test Notification #1]

Expected Ascending Sorting order is:

[AutomationRejectNotification1011, AutomationRejectNotification1021, AutomationRejectNotification|,AutomationTestNotification1, AutomationTestNotification2,AutomationTestNotification100,Test Notfication, Test Notification #1, testDisplay Template, Testing Chrome, Testing Field, testnotif]

Java code:

public static void listSort(List<String> o1, boolean order) {
        final Pattern p = Pattern.compile("^\\d+");
        Comparator<String> c = new Comparator<String>() {
            public int compare(String object1, String object2) {
                Collator collator = Collator.getInstance(Locale.US);
                Matcher m = p.matcher(object1);

                if (!m.find()) {
                    return collator.compare(object1, object2);
                } else {
                    Long number2 = null;
                    Long number1 = Long.parseLong(m.group());

                    m = p.matcher(object2);
                    if (!m.find()) {
                        return collator.compare(object1, object2);
                    } else {

                        number2 = Long.parseLong(m.group());

                        int comparison = number1.compareTo(number2);
                        if (comparison != 0) {
                            return comparison;
                        } else {
                            return collator.compare(object1, object2);
                        }
                    }
                }

            }
        };
        o1.sort(c);

Body:
Your Comparator does not properly implement the contract of the Comparator interface, so all bets are off.  The compare() method must have all of these properties:

sgn(compare(x, y)) == -sgn(compare(y, x)) for all x and y.

((compare(x, y)>0) && (compare(y, z)>0)) implies compare(x, z)>0.

compare(x, y)==0 implies that sgn(compare(x, z))==sgn(compare(y, z)) for all z.

(API docs)

When both strings being compared contain a non-empty decimal digit sequence, you compare only by the numbers, whereas if at least one string is without any digits then you compare via the collator.  That produces these results:

compare("z1", "y") > 0

compare("y", "x3") > 0

compare("z1", "x3") < 0

, which do not conform to the second required property (transitivity).

Possibly what you want to do is is compare the longest leading digitless substrings as a first criterion, breaking any ties by comparing the trailing numbers, if any.  That might look like this:

public static void listSort(List<String> o1, boolean order) {
    final Pattern p = Pattern.compile("([^0-9]*)([0-9]+)?");
    final Collator collator = Collator.getInstance(Locale.US);
    Comparator<String> c = new Comparator<String>() {
        public int compare(String object1, String object2) {
            Matcher m1 = p.matcher(object1);
            Matcher m2 = p.matcher(object2);

            if (!m1.lookingAt() || !m2.lookingAt()) {
                assert false : "Should never happen";
            }

            int result = collator.compare(m1.group(1), m2.group(1));

            if (result == 0) {
                String digits1 = m1.group(2);
                String digits2 = m2.group(2);

                if (digits1 != null && digits2 != null) {
                    Long number1 = Long.valueOf(digits1);
                    Long number2 = Long.valueOf(digits2);
                    result = number1.compareTo(number2);
                } else if (digits1 != null) {
                    result = 1;
                } else if (digits2 != null) {
                    result = -1;
                }
            }

            return result;
        }
    };
    o1.sort(c);
}

That would be consistent with the expected order you presented, but there are other ordering schemes that would also produce the same result for those particular elements.


问:
Why is a non-custom Angular pipe causing my build to not pass, yet all tests pass, and linting passes?
I am working on an Angular 4 project right now, and in it, I'm using the NumberPipe, which I don't even have to import for it to work fine because it comes from CommonModule as I understand.

I use the pipe in my template like so... Pretend results is a number in my component.

```<code><p>{{ results | number : fractionSize }} Results</p>
</code>```

The problem is, it causes my Jenkins build to fail... It says Property 'fractionSize' does not exist on type 'AuctionsComponent'

My question is, since I didn't have to import it to use it in my project, why then is it not available for my tests, and if it needs to be declared in a module, where, and why?

Here is a copy of the message from Jenkins...

```<code>13:54:11 Date: 2017-11-16T20:54:11.047Z
13:54:11 Hash: 17c7bbfe51457a0c0c2a
13:54:11 Time: 34993ms
13:54:11 chunk {0} styles.d1347092f22621d601cc.bundle.css (styles) 402 kB {3} [initial] [rendered]
13:54:11 chunk {1} polyfills.3bc34265385d52184eab.bundle.js (polyfills) 86 bytes {3} [initial] [rendered]
13:54:11 chunk {2} main.e402deade8b026b7d50e.bundle.js (main) 84 bytes {3} [initial] [rendered]
13:54:11 chunk {3} inline.074cdf405b107f2b24b9.bundle.js (inline) 1.45 kB [entry] [rendered]
13:54:11
13:54:11 ERROR in ng:///var/lib/****/workspace/Build/build_gitlab_angular_app/src/app/components/pages/auctions/auctions.component.html (40,40):
Property 'fractionSize' does not exist on type 'AuctionsComponent'.
</code>```

Any help with understanding this would make me happy! :)

答:
The number pipe should look more like this:

```<code>{{ results | number : '1.0-2' }}
</code>```

Where 1 is the minimum number of integer digits; 0 is the minimum number of decimal digits; and 2 is the maximum number of decimal digits.

https://angular.io/api/common/DecimalPipe

Body:
I am working on an Angular 4 project right now, and in it, I'm using the NumberPipe, which I don't even have to import for it to work fine because it comes from CommonModule as I understand.

I use the pipe in my template like so... Pretend results is a number in my component.

{{ results | number : fractionSize }} Results

The problem is, it causes my Jenkins build to fail... It says Property 'fractionSize' does not exist on type 'AuctionsComponent'

My question is, since I didn't have to import it to use it in my project, why then is it not available for my tests, and if it needs to be declared in a module, where, and why?

Here is a copy of the message from Jenkins...

13:54:11 Date: 2017-11-16T20:54:11.047Z
13:54:11 Hash: 17c7bbfe51457a0c0c2a
13:54:11 Time: 34993ms
13:54:11 chunk {0} styles.d1347092f22621d601cc.bundle.css (styles) 402 kB {3} [initial] [rendered]
13:54:11 chunk {1} polyfills.3bc34265385d52184eab.bundle.js (polyfills) 86 bytes {3} [initial] [rendered]
13:54:11 chunk {2} main.e402deade8b026b7d50e.bundle.js (main) 84 bytes {3} [initial] [rendered]
13:54:11 chunk {3} inline.074cdf405b107f2b24b9.bundle.js (inline) 1.45 kB [entry] [rendered]
13:54:11
13:54:11 ERROR in ng:///var/lib/****/workspace/Build/build_gitlab_angular_app/src/app/components/pages/auctions/auctions.component.html (40,40):
Property 'fractionSize' does not exist on type 'AuctionsComponent'.

Any help with understanding this would make me happy! :)

Body:
The number pipe should look more like this:

{{ results | number : '1.0-2' }}

Where 1 is the minimum number of integer digits; 0 is the minimum number of decimal digits; and 2 is the maximum number of decimal digits.

https://angular.io/api/common/DecimalPipe


问:
Best way to handle changing nodes? - C# File Watcher and Clustered File Server
We recently went to a CSVFS clustered file server. I have a file watcher that's monitoring 4 directories for OnCreated and OnRenamed events but whenever the  node changes, it causes a buffer overflow with the error

Too many changes at once in directory

The the watchers are automatically restarted and the process continues to work but begins writing errors when the OnCreated/OnRenamed events are fired.

Cannot access a disposed object.

  Object name: 'FileSystemWatcher'.

  at System.IO.FileSystemWatcher.StartRaisingEvents()

  at System.IO.FileSystemWatcher.set_EnableRaisingEvents(Boolean value)

In the OnCreated method below, if I was to do this, should it work?

```<code>watchit = source as FileSystemWatcher;
</code>```

I don't actually assign the newly created FileSystemWatcher to watchit anywhere else.

More details/code

The watchers are created via a foreach loop when the process initially starts. FileChange is simply a method that determines the type of change, does a bit of work, then triggers the correct action for the change type.

```<code>foreach (string subDir in subDirs)
{
    string localFolder = $"{subDir}";

    watchit = new FileSystemWatcher
                    {
                        Path = localFolder,
                        EnableRaisingEvents = true,
                        IncludeSubdirectories = false,
                        NotifyFilter = NotifyFilters.FileName | NotifyFilters.CreationTime,
                        Filter = watchFor,
                        InternalBufferSize = 65536,
                        SynchronizingObject = null //,
                    };

    watchit.Changed += FileChange;
    watchit.Created += FileChange;
    watchit.Deleted += FileChange;
    watchit.Renamed += OnRename;
    watchit.Error += OnError;
    watchit.EnableRaisingEvents = true;

    watchers.Add(watchit);

    Console.WriteLine($"watching {subDir} for {watchFor}");
}
</code>```

watchit is a static FileSystemWatcher set globally.

```<code>private static async Task<int> OnCreated<T>(object source, FileSystemEventArgs e, string ext)
{
    int insertResult = 0;

    try
    {
        watchit.EnableRaisingEvents = false;
        EventLogWriter.WriteEntry("File: " + e.FullPath + " " + e.ChangeType);
        Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType + " " + DateTime.Now);
        insertResult = await FileHandler.FileHandlers().ConfigureAwait(false);
        watchit.EnableRaisingEvents = true;
        // if (insertResult > 0) File.Delete(e.FullPath);
    }
    catch (Exception ex)
    {
        Logger.Trace($"{ex.Message} {ex.StackTrace} {ex.InnerException}");
        EventLogWriter.WriteEntry($"{ex.Message} {ex.StackTrace} {ex.InnerException}",
        EventLogEntryType.Error);
        watchit.EnableRaisingEvents = true;
    }
    finally
    {
        watchit.EnableRaisingEvents = true;
    }

    return insertResult;
}
</code>```

These are my error handling methods.

```<code>private static void OnError(object source, ErrorEventArgs e)
{
    if (e.GetException().GetType() == typeof(InternalBufferOverflowException))
    {
        EventLogWriter.WriteEntry($"Error: File System Watcher internal buffer overflow at {DateTime.Now}", EventLogEntryType.Warning);
    }
    else
    {
        EventLogWriter.WriteEntry($"Error: Watched directory not accessible at {DateTime.Now}", EventLogEntryType.Warning);
    }

    MailSend.SendUploadEmail($"ASSIST NOTES: {e.GetException().Message}", "The notes service had a failure and should be restarted.", "admins", e.GetException(), MailPriority.High);
    NotAccessibleError(source as FileSystemWatcher, e);
}

    /// <summary>
    /// triggered on accessible error.
    /// </summary>
    /// <param name="source">The source.</param>
    /// <param name="e">The <see cref="ErrorEventArgs"/> instance containing the event data.</param>
    private static void NotAccessibleError(FileSystemWatcher source, ErrorEventArgs e)
        {
        EventLogWriter.WriteEntry($"Not Accessible issue. {e.GetException().Message}" + DateTime.Now.ToString("HH:mm:ss"));

        int iMaxAttempts = 120;
        int iTimeOut = 30000;
        int i = 0;
        string watchPath = source.Path;
        string watchFilter = source.Filter;
        int dirExists = 0;
        try
            {
            dirExists = Directory.GetFiles(watchPath).Length;
            }
        catch (Exception) { }
        try
            {
            while (dirExists == 0 && i < iMaxAttempts)
                {
                i += 1;
                try
                    {
                    source.EnableRaisingEvents = false;
                    if (!Directory.Exists(source.Path))
                        {
                        EventLogWriter.WriteEntry(
                            "Directory Inaccessible " + source.Path + " at " +
                            DateTime.Now.ToString("HH:mm:ss"));
                        Console.WriteLine(
                            "Directory Inaccessible " + source.Path + " at " +
                            DateTime.Now.ToString("HH:mm:ss"));
                        System.Threading.Thread.Sleep(iTimeOut);
                        }
                    else
                        {
                        // ReInitialize the Component
                        source.Dispose();
                        source = null;
                        source = new System.IO.FileSystemWatcher();
                        ((System.ComponentModel.ISupportInitialize)(source)).BeginInit();
                        source.EnableRaisingEvents = true;
                        source.Filter = watchFilter;
                        source.Path = watchPath;
                        source.NotifyFilter = NotifyFilters.FileName | NotifyFilters.CreationTime;
                        source.Created += FileChange;
                        source.Renamed += OnRename;
                        source.Error += new ErrorEventHandler(OnError);
                        ((System.ComponentModel.ISupportInitialize)(source)).EndInit();
                        EventLogWriter.WriteEntry(
                            $"Restarting watcher {watchPath} at " + DateTime.Now.ToString("HH:mm:ss"));
                        dirExists = 1;
                        }
                    }
                catch (Exception error)
                    {
                    EventLogWriter.WriteEntry($"Error trying Restart Service {watchPath} " + error.StackTrace +
                                               " at " + DateTime.Now.ToString("HH:mm:ss"));
                    source.EnableRaisingEvents = false;
                    System.Threading.Thread.Sleep(iTimeOut);
                    }
                }
            //Starts a new version of this console appp if retries exceeded
            //Exits current process
            var runTime = DateTime.UtcNow - Process.GetCurrentProcess().StartTime.ToUniversalTime();
            if (i >= 120 && runTime > TimeSpan.Parse("0:00:30"))
                {
                Process.Start(Assembly.GetExecutingAssembly().Location);
                Environment.Exit(666);
                }
            }
        catch (Exception erw) { }
        }
</code>```

答:
You are trying to do too much work in the FileSystemWatcher events.  The watchers are backed by unmanaged buffers that need to be emptied as quickly as possible to keep up with changes.

Ideally, all the events should be doing is reading some very basic data, like the path that was changed, and the type of change, and throwing that in to queue to be processed on another thread.  That other thread can do the heavy lifting, since it won't be blocking the unmanaged change buffer.

Body:
We recently went to a CSVFS clustered file server. I have a file watcher that's monitoring 4 directories for OnCreated and OnRenamed events but whenever the  node changes, it causes a buffer overflow with the error

Too many changes at once in directory

The the watchers are automatically restarted and the process continues to work but begins writing errors when the OnCreated/OnRenamed events are fired.

Cannot access a disposed object.

  Object name: 'FileSystemWatcher'.

  at System.IO.FileSystemWatcher.StartRaisingEvents()

  at System.IO.FileSystemWatcher.set_EnableRaisingEvents(Boolean value)

In the OnCreated method below, if I was to do this, should it work?

watchit = source as FileSystemWatcher;

I don't actually assign the newly created FileSystemWatcher to watchit anywhere else.

More details/code

The watchers are created via a foreach loop when the process initially starts. FileChange is simply a method that determines the type of change, does a bit of work, then triggers the correct action for the change type.

foreach (string subDir in subDirs)
{
    string localFolder = $"{subDir}";

    watchit = new FileSystemWatcher
                    {
                        Path = localFolder,
                        EnableRaisingEvents = true,
                        IncludeSubdirectories = false,
                        NotifyFilter = NotifyFilters.FileName | NotifyFilters.CreationTime,
                        Filter = watchFor,
                        InternalBufferSize = 65536,
                        SynchronizingObject = null //,
                    };

    watchit.Changed += FileChange;
    watchit.Created += FileChange;
    watchit.Deleted += FileChange;
    watchit.Renamed += OnRename;
    watchit.Error += OnError;
    watchit.EnableRaisingEvents = true;

    watchers.Add(watchit);

    Console.WriteLine($"watching {subDir} for {watchFor}");
}

watchit is a static FileSystemWatcher set globally.

private static async Task<int> OnCreated<T>(object source, FileSystemEventArgs e, string ext)
{
    int insertResult = 0;

    try
    {
        watchit.EnableRaisingEvents = false;
        EventLogWriter.WriteEntry("File: " + e.FullPath + " " + e.ChangeType);
        Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType + " " + DateTime.Now);
        insertResult = await FileHandler.FileHandlers().ConfigureAwait(false);
        watchit.EnableRaisingEvents = true;
        // if (insertResult > 0) File.Delete(e.FullPath);
    }
    catch (Exception ex)
    {
        Logger.Trace($"{ex.Message} {ex.StackTrace} {ex.InnerException}");
        EventLogWriter.WriteEntry($"{ex.Message} {ex.StackTrace} {ex.InnerException}",
        EventLogEntryType.Error);
        watchit.EnableRaisingEvents = true;
    }
    finally
    {
        watchit.EnableRaisingEvents = true;
    }

    return insertResult;
}

These are my error handling methods.

private static void OnError(object source, ErrorEventArgs e)
{
    if (e.GetException().GetType() == typeof(InternalBufferOverflowException))
    {
        EventLogWriter.WriteEntry($"Error: File System Watcher internal buffer overflow at {DateTime.Now}", EventLogEntryType.Warning);
    }
    else
    {
        EventLogWriter.WriteEntry($"Error: Watched directory not accessible at {DateTime.Now}", EventLogEntryType.Warning);
    }

    MailSend.SendUploadEmail($"ASSIST NOTES: {e.GetException().Message}", "The notes service had a failure and should be restarted.", "admins", e.GetException(), MailPriority.High);
    NotAccessibleError(source as FileSystemWatcher, e);
}

    ///
    /// triggered on accessible error.
    ///
    /// <param name="source">The source.</param>
    /// <param name="e">The <see cref="ErrorEventArgs"/> instance containing the event data.</param>
    private static void NotAccessibleError(FileSystemWatcher source, ErrorEventArgs e)
        {
        EventLogWriter.WriteEntry($"Not Accessible issue. {e.GetException().Message}" + DateTime.Now.ToString("HH:mm:ss"));

        int iMaxAttempts = 120;
        int iTimeOut = 30000;
        int i = 0;
        string watchPath = source.Path;
        string watchFilter = source.Filter;
        int dirExists = 0;
        try
            {
            dirExists = Directory.GetFiles(watchPath).Length;
            }
        catch (Exception) { }
        try
            {
            while (dirExists == 0 && i < iMaxAttempts)
                {
                i += 1;
                try
                    {
                    source.EnableRaisingEvents = false;
                    if (!Directory.Exists(source.Path))
                        {
                        EventLogWriter.WriteEntry(
                            "Directory Inaccessible " + source.Path + " at " +
                            DateTime.Now.ToString("HH:mm:ss"));
                        Console.WriteLine(
                            "Directory Inaccessible " + source.Path + " at " +
                            DateTime.Now.ToString("HH:mm:ss"));
                        System.Threading.Thread.Sleep(iTimeOut);
                        }
                    else
                        {
                        // ReInitialize the Component
                        source.Dispose();
                        source = null;
                        source = new System.IO.FileSystemWatcher();
                        ((System.ComponentModel.ISupportInitialize)(source)).BeginInit();
                        source.EnableRaisingEvents = true;
                        source.Filter = watchFilter;
                        source.Path = watchPath;
                        source.NotifyFilter = NotifyFilters.FileName | NotifyFilters.CreationTime;
                        source.Created += FileChange;
                        source.Renamed += OnRename;
                        source.Error += new ErrorEventHandler(OnError);
                        ((System.ComponentModel.ISupportInitialize)(source)).EndInit();
                        EventLogWriter.WriteEntry(
                            $"Restarting watcher {watchPath} at " + DateTime.Now.ToString("HH:mm:ss"));
                        dirExists = 1;
                        }
                    }
                catch (Exception error)
                    {
                    EventLogWriter.WriteEntry($"Error trying Restart Service {watchPath} " + error.StackTrace +
                                               " at " + DateTime.Now.ToString("HH:mm:ss"));
                    source.EnableRaisingEvents = false;
                    System.Threading.Thread.Sleep(iTimeOut);
                    }
                }
            //Starts a new version of this console appp if retries exceeded
            //Exits current process
            var runTime = DateTime.UtcNow - Process.GetCurrentProcess().StartTime.ToUniversalTime();
            if (i >= 120 && runTime > TimeSpan.Parse("0:00:30"))
                {
                Process.Start(Assembly.GetExecutingAssembly().Location);
                Environment.Exit(666);
                }
            }
        catch (Exception erw) { }
        }


问:
python - how to make a float to float function behave elementwise on lists?
I have the following code:

```<code>def tau_r(u):
    return (u_1 < u < u_2) * (T1 - T2) + T2
if __name__ == "__main__":
    figure()
    plot(u, tau_r(u))
    show()
</code>```

I get the following error when I run it:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

I suppose it's because it is seeing u as a list while it should perform the task on each element of the list separately.
How can I fix this?

答:
You can apply the same function to all elements of a list by using map. It'll return a new list with each returned value from the function.

```<code>plot(u, list(map(tau_r, u)))
</code>```

Body:
I have the following code:

def tau_r(u):
    return (u_1 < u < u_2) * (T1 - T2) + T2
if __name__ == "__main__":
    figure()
    plot(u, tau_r(u))
    show()

I get the following error when I run it:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

I suppose it's because it is seeing u as a list while it should perform the task on each element of the list separately.
How can I fix this?

Body:
You can apply the same function to all elements of a list by using map. It'll return a new list with each returned value from the function.

plot(u, list(map(tau_r, u)))


问:
How do I use keras to load my own customized dataset for convolution neural network
Below is sample code for imdb dataset.I am a beginner and following a tutorial, I am trying to load my own dataset in keras.How would I modify the code.I would be very grateful</p>

```<code>import keras
#Using keras to load the dataset with the top_words
max_features = 10000 #max number of words to include, words are ranked by how often they occur (in training set)
max_review_length = 1600

(X_train, y_train), (X_test, y_test) = imdb.load_data(nb_words=max_features)
print 'loaded dataset...'
#Pad the sequence to the same length
X_train = sequence.pad_sequences(X_train, maxlen=max_review_length)
X_test = sequence.pad_sequences(X_test, maxlen=max_review_length)

index_dict = keras.datasets.imdb.get_word_index()
</code>```

答:
Here's a simple solution with Pandas and CountVectorizer. You'll then need to pad the data and split into test and train as above.</p>

```<code>import numpy as np
import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer

data = {
    'label': [0, 1, 0, 1],
    'text': ['first bit of text', 'second bit of text', 'third text', 'text number four']
}
data = pd.DataFrame.from_dict(data)

# Form vocab dictionary
vectorizer = CountVectorizer()
vectorizer.fit_transform(data['text'].tolist())
vocab_text = vectorizer.vocabulary_

# Convert text
def convert_text(text):
    text_list = text.split(' ')
    return [vocab_text[t]+1 for t in text_list]

data['text'] = data['text'].apply(convert_text)

# Get X and y matrices
y = np.array(data['label'])
X = np.array(data['text'])
</code>```

Body:
Below is sample code for imdb dataset.I am a beginner and following a tutorial, I am trying to load my own dataset in keras.How would I modify the code.I would be very grateful

import keras
#Using keras to load the dataset with the top_words
max_features = 10000 #max number of words to include, words are ranked by how often they occur (in training set)
max_review_length = 1600

(X_train, y_train), (X_test, y_test) = imdb.load_data(nb_words=max_features)
print 'loaded dataset...'
#Pad the sequence to the same length
X_train = sequence.pad_sequences(X_train, maxlen=max_review_length)
X_test = sequence.pad_sequences(X_test, maxlen=max_review_length)

index_dict = keras.datasets.imdb.get_word_index()

Body:
Here's a simple solution with Pandas and CountVectorizer. You'll then need to pad the data and split into test and train as above.

import numpy as np
import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer

data = {
    'label': [0, 1, 0, 1],
    'text': ['first bit of text', 'second bit of text', 'third text', 'text number four']
}
data = pd.DataFrame.from_dict(data)

# Form vocab dictionary
vectorizer = CountVectorizer()
vectorizer.fit_transform(data['text'].tolist())
vocab_text = vectorizer.vocabulary_

# Convert text
def convert_text(text):
    text_list = text.split(' ')
    return [vocab_text[t]+1 for t in text_list]

data['text'] = data['text'].apply(convert_text)

# Get X and y matrices
y = np.array(data['label'])
X = np.array(data['text'])


问:
The best way to write code in Julia working on GPU's via ArrayFire
In Julia, I saw principally that to acelerate and optimizing codes when I work on a matrix, es better e.g.

-work by columns instead of by rows, this is for the way which Julia store the matrix.

-On loops could use @inbounds and @simd macros

-any function, macros or methods you could recommend it's welcome  :D

But it seems that the above examples do not work when I use the ArrayFire package with a matrix stored on the GPU, similar codes in the CPU and GPU do not seem to favor the GPU that runs much slower in some cases, I think it shouldn't be like that, I think the problem is in the way of writing the code. Any help will be welcome

答:
GPU computing should be done on optimized GPU kernels as much as possible. Indexing a GPU array is a small kernel that copies one value back to the CPU. This is really really bad for performance, so you should almost never index a GPUArray unless you have to (this is true for any implementation! It's just a hardware problem!)

Thus, instead of writing looping code for GPUs, you should write broadcasting ("vectorized") code. With the v0.6 broadcast changes, broadcasted operations are nearly as efficient as loops anyways (unless you hit this bug), so there's no reason to avoid them in generic code. However, there are cases where broadcasting is faster than looping, and GPUs is one big case.

Let me explain a little bit why. When you do the code:

```<code>@. A = B*C + D*E
</code>```

it lowers to

```<code>A .= B.*C .+ D.*E
</code>```

which then lowers to:

```<code>broadcast!((b,c,d,e)->b*c + d*e,A,B,C,D,E)
</code>```

Notice that in there you have a fused anonymous function for the entire broadcast. For GPUArrays, this is then overwritten so that way a single GPU kernel is automatically created that performs this fused operation element-wise. Thus only one GPU kernel is required to do this whole operation! Notice that this is even more efficient than the R/Python/MATLAB way of doing GPU computing since those vectorized forms have temporaries and would require 4 kernels here, but this has no temporary arrays and is a single kernel, which is pretty much exactly how you'd write it if you were writing the kernel yourself. So if you exploit broadcast, then your GPU calculations will be fast.

Body:
GPU computing should be done on optimized GPU kernels as much as possible. Indexing a GPU array is a small kernel that copies one value back to the CPU. This is really really bad for performance, so you should almost never index a GPUArray unless you have to (this is true for any implementation! It's just a hardware problem!)

Thus, instead of writing looping code for GPUs, you should write broadcasting ("vectorized") code. With the v0.6 broadcast changes, broadcasted operations are nearly as efficient as loops anyways (unless you hit this bug), so there's no reason to avoid them in generic code. However, there are cases where broadcasting is faster than looping, and GPUs is one big case.

Let me explain a little bit why. When you do the code:

@. A = B*C + D*E

it lowers to

A .= B.*C .+ D.*E

which then lowers to:

broadcast!((b,c,d,e)->b*c + d*e,A,B,C,D,E)

Notice that in there you have a fused anonymous function for the entire broadcast. For GPUArrays, this is then overwritten so that way a single GPU kernel is automatically created that performs this fused operation element-wise. Thus only one GPU kernel is required to do this whole operation! Notice that this is even more efficient than the R/Python/MATLAB way of doing GPU computing since those vectorized forms have temporaries and would require 4 kernels here, but this has no temporary arrays and is a single kernel, which is pretty much exactly how you'd write it if you were writing the kernel yourself. So if you exploit broadcast, then your GPU calculations will be fast.


问:
mysqldump & gzip commands to properly create a compressed file of a MySQL database using crontab
I am having problems with getting a crontab to work. I want to automate a MySQL database backup.

The setup:

Debian GNU/Linux 7.3 (wheezy)

MySQL Server version: 5.5.33-0+wheezy1(Debian)

directories user, backup and backup2 have 755 permission

The user names for MySQL db and Debian account are the same

From the shell this command works

```<code>mysqldump -u user -p[user_password] [database_name] | gzip > dumpfilename.sql.gz
</code>```

When I place this in a crontab using crontab -e

```<code>* * /usr/bin/mysqldump -u user -pupasswd mydatabase | gzip> /home/user/backup/mydatabase-backup-`date +\%m\%d_\%Y`.sql.gz >/dev/null 2>&1
</code>```

A file is created every minute in /home/user/backup directory, but has 0 bytes.

However when I redirect this output to a second directory, backup2, I note that the proper mysqldumpfile duly compressed is created in it. I am unable to figure what is the mistake that I am making that results in a 0 byte file in the first directory and the expected output in the second directory.

```<code>* * /usr/bin/mysqldump -u user -pupasswd my-database | gzip> /home/user/backup/mydatabase-backup-`date +\%m\%d_\%Y`.sql.gz >/home/user/backup2/mydatabase-backup-`date +\%m\%d_\%Y`.sql.gz 2>&1
</code>```

I would greatly appreciate an explanation.

Thanks

答:
if you need to add a date-time to your backup file name (Centos7) use the following:

```<code>/usr/bin/mysqldump -u USER -pPASSWD DBNAME | gzip > ~/backups/db.$(date +%F.%H%M%S).sql.gz
</code>```

this will create the file: db.2017-11-17.231537.sql.gz

Body:
I am having problems with getting a crontab to work. I want to automate a MySQL database backup.

The setup:

Debian GNU/Linux 7.3 (wheezy)

MySQL Server version: 5.5.33-0+wheezy1(Debian)

directories user, backup and backup2 have 755 permission

The user names for MySQL db and Debian account are the same

From the shell this command works

mysqldump -u user -p[user_password] [database_name] | gzip > dumpfilename.sql.gz

When I place this in a crontab using crontab -e

* * /usr/bin/mysqldump -u user -pupasswd mydatabase | gzip> /home/user/backup/mydatabase-backup-`date +\%m\%d_\%Y`.sql.gz >/dev/null 2>&1

A file is created every minute in /home/user/backup directory, but has 0 bytes.

However when I redirect this output to a second directory, backup2, I note that the proper mysqldumpfile duly compressed is created in it. I am unable to figure what is the mistake that I am making that results in a 0 byte file in the first directory and the expected output in the second directory.

* * /usr/bin/mysqldump -u user -pupasswd my-database | gzip> /home/user/backup/mydatabase-backup-`date +\%m\%d_\%Y`.sql.gz >/home/user/backup2/mydatabase-backup-`date +\%m\%d_\%Y`.sql.gz 2>&1

I would greatly appreciate an explanation.

Thanks

Body:
if you need to add a date-time to your backup file name (Centos7) use the following:

/usr/bin/mysqldump -u USER -pPASSWD DBNAME | gzip > ~/backups/db.$(date +%F.%H%M%S).sql.gz

this will create the file: db.2017-11-17.231537.sql.gz


问:
ASP.NET IIS and framework
I have one ASP.NET web application projrct, created in Visual Studio 2008, .NET 3.5 Framework, IIS 6.1 and I'm using Ajax updatepanel, cache options for caching the datatable in a gridview. This project is working good in local, but when I deployed in a cert environment (.NET Framework 2.0 and IIS 6.0) I faced that caching issue.

So that, now I'm trying to change the project from 3.5 to 2.0 framework. But I'm facing an Ajax update panel error.

How can this problem be fixed?

答:
You mean the target framework? You can right click the application name and then click on Property Pages, in that go to Build and then choose the target framework to 2.0.

Also, have a look at this:
http://msdn2.microsoft.com/en-us/library/bb398791(VS.90).aspx
reference : http://forums.asp.net/t/1194067.aspx

It will not be very straight forward though. As there may be some language features that are only available in 3.5.

Title: ASP.NET IIS and framework


问:
Weird behavior in bash and .bashrc
I have added echo thisIsMyBash at the end of my .bashrc file. Now when I write create a new terminal with ctrl+alt+t, thisIsMyBash is written a the beginning. This is as expected.

Now when I type /bin/bash in my terminal thisIsMyBash is also displayed in my terminal.

But when I write /bin/bash -c "source ~/.bashrc" in my terminal, nothing is written. Why?

Also when I actually write /bin/bash -c "source ~/.bashrc" && exec /bin/bash -li thisIsMyBash also is displayed. Why that?

Any idea?

答:
If you use the "-i" option of bash it will work as desired. This option make the shell interactive. Try this:

```<code>/bin/bash -i -c "source ~/.bashrc"
</code>```

Take a look here.

Title: Weird behavior in bash and .bashrc

Body:
If you use the "-i" option of bash it will work as desired. This option make the shell interactive. Try this:

/bin/bash -i -c "source ~/.bashrc"

Take a look here.


问:
Access bokeh server URL
I'd like to access my bokeh application's URL.

I tried:

```<code>curdoc().session_context.server_context.application_context.url
</code>```

But it only gives me the last part of the URL.

Also, when acessing the HTTP request object from

```<code>curdoc().session_context.request
</code>```

Only the arguments member can be queried (as defined in https://docs.bokeh.org/en/latest/docs/user_guide/server.html#accessing-the-http-request).

How do I get the complete URL of the running bokeh application?

Thanks

答:
As suggested in the comments, this does not seem possible when using the bokeh server command.

I managed to use os.getenv('HOSTNAME') and session_context.server_context.application_context.url  to rebuild the full url.

Thanks

ContentLicense: CC BY-SA 4.0

Title: Access bokeh server URL

Body:
I'd like to access my bokeh application's URL.

I tried:

curdoc().session_context.server_context.application_context.url

But it only gives me the last part of the URL.

Also, when acessing the HTTP request object from

curdoc().session_context.request

Only the arguments member can be queried (as defined in https://docs.bokeh.org/en/latest/docs/user_guide/server.html#accessing-the-http-request).

How do I get the complete URL of the running bokeh application?

Thanks


问:
searching for a character throughout 4 strings in c using strchr
I'm having some trouble figuring out why when I run the program it won't let me scan the character I want to search for. It just jumps straight to the last printf statement.</p>

```<code>int main()
{
char s1[100], s2[100], s3[100], s4[100];
char character
char *charSearch[3] = {s1, s2, s3, s4};
int counter = 0;
int i;

printf("Enter 4 lines of text: \n");
scanf("%s %s %s %s", &s1, &s2, &s3, &s4);
printf("Enter a any character to search:\n");

scanf("%c", &character);

for(i = 0; i < 3; i++)
{
while(charSearch[i] = strchr(  charSearch, character ))
{
counter++;
charsearch[i]++;
}
}
printf("Total occurrences of character %c is %d", character, counter);

return 0;
}
</code>```

答:
It's because when reading input using scanf, the input is read after the return key is pressed but the newline generated by the return key is not consumed by scanf, which means the next time you read a char from standard input there will be a newline ready to be read.

Source : Simple C scanf does not work?

Body:
I'm having some trouble figuring out why when I run the program it won't let me scan the character I want to search for. It just jumps straight to the last printf statement.

int main()
{
char s1[100], s2[100], s3[100], s4[100];
char character
char *charSearch[3] = {s1, s2, s3, s4};
int counter = 0;
int i;

printf("Enter 4 lines of text: \n");
scanf("%s %s %s %s", &s1, &s2, &s3, &s4);
printf("Enter a any character to search:\n");

scanf("%c", &character);

for(i = 0; i < 3; i++)
{
while(charSearch[i] = strchr(  charSearch, character ))
{
counter++;
charsearch[i]++;
}
}
printf("Total occurrences of character %c is %d", character, counter);

return 0;
}


问:
what is the fastest way to assign data array items to range values
I am developing an excel client to a SQL server data base.

When I select data from the data base to the client records are saved in arrays. These arrays are then "injected" into Excel sheets using an array of variant.

This technique is far faster than assigning individual cell values BUT seems to fail in some specific context.

When the data value is vbNullString the range cell corresponding to the item is not assigned. Worst if the first item is vbNullString, none of the items are saved to the range.
My guess is that the vbNullString is translated to null as a variant and the variant array has the wrong dimension.

Is there any other explanation ?

For instance

```<code>ByRef loTable As ListObject,
ByRef sItems() As String
</code>```

are parameters of a sub executing the following code where
loTable is an Excel Table (ListObject) and  sItems the data I want to assign to the range of the Excel Table loTable

```<code>Dim lCount as Long
Dim vItems() as Variant
lCount = UBound(sItems)-LBound(sItems)+1
'size vItems as a 2D array - required to fetch a range
If (lCount > 0) Then ReDim vItems(1 To lCount, 1 To 1)
'copy string to variant
Dim i As Integer
For i = LBound(sItems) To UBound(sItems)
    vItems(i, 1) = sItems(i)
Next i
Dim olrs As ListRows
Set olrs = loTable.ListRows
With loTable
    If (lCount > 0) Then
        If (Not (.DataBodyRange Is Nothing)) Then .DataBodyRange.Delete
        olrs.Add
        If (lCount = 1) Then
            olrs(olrs.Count).Range.Cells(1, 1).Value = sItems(LBound(sItems))
        Else
            .DataBodyRange.Resize(lCount, 1).Value = vItems
        End If
    Else
        .DataBodyRange.Delete
    End If
End With 'loTable
</code>```

I come to the question : have you tried such a range (of a table) value assignment and how to cope with null items in an array for a fast assignment.
Looping over the array items and adding one by one just takes for ever.

答:
Would something like this help?</p>

```<code>'Declarations section
Private Const gsPROVIDER as String = [Provider]
Private Const gsDATA_SOURCE as String = [Source]
Private Const gsINITIAL_CATALOG as String = [Catalog]
Private Const gsUSER_ID as String = [User ID]
Private Const gsPASSWORD as String = [Password]

Private Sub Test
    Dim rsData As Object
    Dim sConnect As String
    Dim sSQL As String

    sConnect = "Provider=" & gsPROVIDER & _
               "Data Source=" & gsDATA_SOURCE & _
               "Initial Catalog=" & gsINITIAL_CATALOG & _
               "User ID=" & gsUSER_ID & _
               "Password=" & gsPASSWORD
    sSQL = 'SQL in a string

    Set rsData = CreateObject("ADODB.Recordset")
    rsData.Open sSQL, sConnect

    If Not rsData.EOF Then
        Worksheets(1).ListObjects(loTable).DataBodyRange.CopyFromRecordset rsData
    Else
        MsgBox "No data found!", vbCritical, "Error!"
    End If

    rsData.Close
    Set rsData = Nothing
End Sub
</code>```

Body:
I am developing an excel client to a SQL server data base.

When I select data from the data base to the client records are saved in arrays. These arrays are then "injected" into Excel sheets using an array of variant.

This technique is far faster than assigning individual cell values BUT seems to fail in some specific context.

When the data value is vbNullString the range cell corresponding to the item is not assigned. Worst if the first item is vbNullString, none of the items are saved to the range.
My guess is that the vbNullString is translated to null as a variant and the variant array has the wrong dimension.

Is there any other explanation ?

For instance

ByRef loTable As ListObject,
ByRef sItems() As String

are parameters of a sub executing the following code where
loTable is an Excel Table (ListObject) and  sItems the data I want to assign to the range of the Excel Table loTable

Dim lCount as Long
Dim vItems() as Variant
lCount = UBound(sItems)-LBound(sItems)+1
'size vItems as a 2D array - required to fetch a range
If (lCount > 0) Then ReDim vItems(1 To lCount, 1 To 1)
'copy string to variant
Dim i As Integer
For i = LBound(sItems) To UBound(sItems)
    vItems(i, 1) = sItems(i)
Next i
Dim olrs As ListRows
Set olrs = loTable.ListRows
With loTable
    If (lCount > 0) Then
        If (Not (.DataBodyRange Is Nothing)) Then .DataBodyRange.Delete
        olrs.Add
        If (lCount = 1) Then
            olrs(olrs.Count).Range.Cells(1, 1).Value = sItems(LBound(sItems))
        Else
            .DataBodyRange.Resize(lCount, 1).Value = vItems
        End If
    Else
        .DataBodyRange.Delete
    End If
End With 'loTable

I come to the question : have you tried such a range (of a table) value assignment and how to cope with null items in an array for a fast assignment.
Looping over the array items and adding one by one just takes for ever.

Body:
Would something like this help?

'Declarations section
Private Const gsPROVIDER as String = [Provider]
Private Const gsDATA_SOURCE as String = [Source]
Private Const gsINITIAL_CATALOG as String = [Catalog]
Private Const gsUSER_ID as String = [User ID]
Private Const gsPASSWORD as String = [Password]

Private Sub Test
    Dim rsData As Object
    Dim sConnect As String
    Dim sSQL As String

    sConnect = "Provider=" & gsPROVIDER & _
               "Data Source=" & gsDATA_SOURCE & _
               "Initial Catalog=" & gsINITIAL_CATALOG & _
               "User ID=" & gsUSER_ID & _
               "Password=" & gsPASSWORD
    sSQL = 'SQL in a string

    Set rsData = CreateObject("ADODB.Recordset")
    rsData.Open sSQL, sConnect

    If Not rsData.EOF Then
        Worksheets(1).ListObjects(loTable).DataBodyRange.CopyFromRecordset rsData
    Else
        MsgBox "No data found!", vbCritical, "Error!"
    End If

    rsData.Close
    Set rsData = Nothing
End Sub


答:
A Russian hacker will help you.:)

For starters according to the C Standard the function main without parameters shall be declared like

```<code>int main( void )
</code>```

Try not to use magic numbers. The compiler shall issue a diagnostic message relative to this declaration

```<code>char *charSearch[3] = {s1, s2, s3, s4};
</code>```

because there are more initializers than elements in the array.

This statement with scanf is unsafe and moreover the argument expressions are invalid.

```<code>scanf("%s %s %s %s", &s1, &s2, &s3, &s4);
</code>```

It is desirable to place a blank in the format specifier in this statement

```<code>scanf("%c", &character);
      ^^^^
</code>```

Otherwise blank characters (as for example the new ,line character) can be read.

The condition in the while statement does not make sense

```<code>while(charSearch[i] = strchr(  charSearch, character ))
</code>```

The program can look the following way

```<code>#include <stdio.h>
#include <string.h>

#define SIZE 100

int main( void )
{
    char s1[SIZE], s2[SIZE], s3[SIZE], s4[SIZE];
    char * charSearch[] = { s1, s2, s3, s4 };
    const size_t N = sizeof(charSearch) / sizeof(*charSearch);
    char character;

    size_t counter = 0;

    printf( "Enter %zu lines of text: \n", N );

    for (size_t i = 0; i < N; i++)
    {
        charSearch[i][0] = '\0';
        fgets(charSearch[i], SIZE, stdin);
    }

    printf("Enter any character to search:\n");

    scanf(" %c", &character );

    for (size_t i = 0; i < N; i++)
    {
        for (char *p = charSearch[i]; ( p = strchr(p, character) ) != NULL; ++p )
        {
            ++counter;
        }
    }

    printf("Total occurrences of character %c is %zu\n", character, counter);

    return 0;
}
</code>```

The program output might look like

```<code>Enter 4 lines of text:
Hello World
How are you?
Stackoverflow
I'm learning C
Enter any character to search:
e
Total occurrences of character e is 4
</code>```

Title: searching for a character throughout 4 strings in c using strchr

Body:
A Russian hacker will help you.:)

For starters according to the C Standard the function main without parameters shall be declared like

int main( void )

Try not to use magic numbers. The compiler shall issue a diagnostic message relative to this declaration

char *charSearch[3] = {s1, s2, s3, s4};

because there are more initializers than elements in the array.

This statement with scanf is unsafe and moreover the argument expressions are invalid.

scanf("%s %s %s %s", &s1, &s2, &s3, &s4);

It is desirable to place a blank in the format specifier in this statement

scanf("%c", &character);
      ^^^^

Otherwise blank characters (as for example the new ,line character) can be read.

The condition in the while statement does not make sense

while(charSearch[i] = strchr(  charSearch, character ))

The program can look the following way

#include <stdio.h>
#include <string.h>

#define SIZE 100

int main( void )
{
    char s1[SIZE], s2[SIZE], s3[SIZE], s4[SIZE];
    char * charSearch[] = { s1, s2, s3, s4 };
    const size_t N = sizeof(charSearch) / sizeof(*charSearch);
    char character;

    size_t counter = 0;

    printf( "Enter %zu lines of text: \n", N );

    for (size_t i = 0; i < N; i++)
    {
        charSearch[i][0] = '\0';
        fgets(charSearch[i], SIZE, stdin);
    }

    printf("Enter any character to search:\n");

    scanf(" %c", &character );

    for (size_t i = 0; i < N; i++)
    {
        for (char *p = charSearch[i]; ( p = strchr(p, character) ) != NULL; ++p )
        {
            ++counter;
        }
    }

    printf("Total occurrences of character %c is %zu\n", character, counter);

    return 0;
}

The program output might look like

Enter 4 lines of text:
Hello World
How are you?
Stackoverflow
I'm learning C
Enter any character to search:
e
Total occurrences of character e is 4


问:
Set Timeout and NgZone in Angular
I saw the following today in my code base and am trying to wrap my head around what it could be doing:

```<code>public ngOnInit(): void {
    this.siteTitle = this.modalService.site ? this.modalService.site.siteTitle : null;
        setTimeout(() => {
            if (!this.modalService.site) {
                this.ngZone.run(() => {
                    this.modalService.close();
                });
            }
        }, 0);
}
</code>```

I've been reading some articles such as this one but still would like some clarification. I know that because the setTimeout parameter is 0 it will still be placed into the event queue and will execute once all other non-JS pieces are finished.

Thanks

答:
I don't have all the information to write a definitive answer but I use ngZone.run sometimes to force the refresh of the component.

Now using this in a setTimeout leads me to believe that something occurs elsewhere changing the state of the view but somehow requires a manual refresh to redraw the changes. This is usually a js-only library make changes that angular doesn't know about.

Title: Set Timeout and NgZone in Angular

Body:
I saw the following today in my code base and am trying to wrap my head around what it could be doing:

public ngOnInit(): void {
    this.siteTitle = this.modalService.site ? this.modalService.site.siteTitle : null;
        setTimeout(() => {
            if (!this.modalService.site) {
                this.ngZone.run(() => {
                    this.modalService.close();
                });
            }
        }, 0);
}

I've been reading some articles such as this one but still would like some clarification. I know that because the setTimeout parameter is 0 it will still be placed into the event queue and will execute once all other non-JS pieces are finished.

Thanks


问:
How do I select rows in a data frame before and after a condition is met?
I'm searching the web for a few a days now and I can't find a solution to my (probably easy to solve) problem.

I have huge data frames with 4 variables and over a million observations each. Now I want to select 100 rows before, all rows while and 1000 rows after a specific condition is met and fill the rest with NA's. I tried it with a for loop and if/ifelse but it doesn't work so far. I think it shouldn't be a big thing, but in the moment I just don't get the hang of it.

I create the data using:

```<code>foo<-data.frame(t = 1:15, a = sample(1:15), b = c(1,1,1,1,1,4,4,4,4,1,1,1,1,1,1), c = sample(1:15))
</code>```

My Data looks like this:

```<code>ID    t   a   b   c
1     1   4   1   7
2     2   7   1   10
3     3   10  1   6
4     4   2   1   4
5     5   13  1   9
6     6   15  4   3
7     7   8   4   15
8     8   3   4   1
9     9   9   4   2
10   10   14  1   8
11   11   5   1   11
12   12   11  1   13
13   13   12  1   5
14   14   6   1   14
15   15   1   1   12
</code>```

What I want is to pick the value of a (in this example) 2 rows before, all rows while and 3 rows after the value of b is >1 and fill the rest with NA's. [Because this is just an example I guess you can imagine that after these 15 rows there are more rows with the value for b changing from 1 to 4 several times (I did not post it, so I won't spam the question with unnecessary data).]
So I want to get something like:

```<code>ID    t   a   b   c   d
1     1   4   1   7  NA
2     2   7   1   10 NA
3     3   10  1   6  NA
4     4   2   1   4   2
5     5   13  1   9  13
6     6   15  4   3  15
7     7   8   4   15  8
8     8   3   4   1   3
9     9   9   4   2   9
10   10   14  1   8  14
11   11   5   1   11  5
12   12   11  1   13 11
13   13   12  1   5  NA
14   14   6   1   14 NA
15   15   1   1   12 NA
</code>```

I'm thankful for any help.

Thank you.

Best regards,
Chris

答:
here is the same attempt as missuse, but with data.table:

```<code>library(data.table)
foo<-data.frame(t = 1:11, a = sample(1:11), b = c(1,1,1,4,4,4,4,1,1,1,1), c = sample(1:11))
DT <- setDT(foo)
DT[ unique(c(DT[,.I[b>1] ],DT[,.I[b>1]+3 ],DT[,.I[b>1]-2 ])), d := a]

     t  a b  c  d
 1:  1 10 1  2 NA
 2:  2  6 1 10  6
 3:  3  5 1  7  5
 4:  4 11 4  4 11
 5:  5  4 4  9  4
 6:  6  8 4  5  8
 7:  7  2 4  8  2
 8:  8  3 1  3  3
 9:  9  7 1  6  7
10: 10  9 1  1  9
11: 11  1 1 11 NA
</code>```

Here

```<code>unique(c(DT[,.I[b>1] ],DT[,.I[b>1]+3 ],DT[,.I[b>1]-2 ]))
</code>```

gives you your desired indixes : the unique indices of the line for your condition, the same indices+3 and -2.

Body:
I'm searching the web for a few a days now and I can't find a solution to my (probably easy to solve) problem.

I have huge data frames with 4 variables and over a million observations each. Now I want to select 100 rows before, all rows while and 1000 rows after a specific condition is met and fill the rest with NA's. I tried it with a for loop and if/ifelse but it doesn't work so far. I think it shouldn't be a big thing, but in the moment I just don't get the hang of it.

I create the data using:

foo<-data.frame(t = 1:15, a = sample(1:15), b = c(1,1,1,1,1,4,4,4,4,1,1,1,1,1,1), c = sample(1:15))

My Data looks like this:

ID    t   a   b   c
1     1   4   1   7
2     2   7   1   10
3     3   10  1   6
4     4   2   1   4
5     5   13  1   9
6     6   15  4   3
7     7   8   4   15
8     8   3   4   1
9     9   9   4   2
10   10   14  1   8
11   11   5   1   11
12   12   11  1   13
13   13   12  1   5
14   14   6   1   14
15   15   1   1   12

What I want is to pick the value of a (in this example) 2 rows before, all rows while and 3 rows after the value of b is >1 and fill the rest with NA's. [Because this is just an example I guess you can imagine that after these 15 rows there are more rows with the value for b changing from 1 to 4 several times (I did not post it, so I won't spam the question with unnecessary data).]
So I want to get something like:

ID    t   a   b   c   d
1     1   4   1   7  NA
2     2   7   1   10 NA
3     3   10  1   6  NA
4     4   2   1   4   2
5     5   13  1   9  13
6     6   15  4   3  15
7     7   8   4   15  8
8     8   3   4   1   3
9     9   9   4   2   9
10   10   14  1   8  14
11   11   5   1   11  5
12   12   11  1   13 11
13   13   12  1   5  NA
14   14   6   1   14 NA
15   15   1   1   12 NA

I'm thankful for any help.

Thank you.

Best regards,
Chris

Body:
here is the same attempt as missuse, but with data.table:

library(data.table)
foo<-data.frame(t = 1:11, a = sample(1:11), b = c(1,1,1,4,4,4,4,1,1,1,1), c = sample(1:11))
DT <- setDT(foo)
DT[ unique(c(DT[,.I[b>1] ],DT[,.I[b>1]+3 ],DT[,.I[b>1]-2 ])), d := a]

     t  a b  c  d
 1:  1 10 1  2 NA
 2:  2  6 1 10  6
 3:  3  5 1  7  5
 4:  4 11 4  4 11
 5:  5  4 4  9  4
 6:  6  8 4  5  8
 7:  7  2 4  8  2
 8:  8  3 1  3  3
 9:  9  7 1  6  7
10: 10  9 1  1  9
11: 11  1 1 11 NA

Here

unique(c(DT[,.I[b>1] ],DT[,.I[b>1]+3 ],DT[,.I[b>1]-2 ]))

gives you your desired indixes : the unique indices of the line for your condition, the same indices+3 and -2.


问:
Bulk Edit Update Multiple Rows in ASP.Net GridView using CheckBoxes
you can see VT_AClReport Table design In the below HTML Markup I have a simple ASP.Net GridView with 3 columns.

First column containing the CheckBox, second column containing a Label for display ID and Access Path of the folder respectively and the third column containing a Label and DropDownList for display and edit status of the folder respectively.

Here I am using GridView with paging to display the data, and the data is about millions of rows. When I click on submit button to update the checkbox selected rows, execution time is taking too much to update the rows in table.

For Example: for 5000 rows = 26 min.
Can anyone help me to resolve this issue and reduce the execution time to update all the records within few seconds.

Please see the code:

```<code>        <asp:GridView ID="gvACLReport" runat="server" AutoGenerateColumns="False"CssClass="mgrid" EmptyDataText="No Records Exists..." DataKeyNames="ACLId" ShowFooter="True" HorizontalAlign="Center" Width="100%" AllowPaging="True" EnableSortingAndPagingCallback="True" PageSize="500" AllowSorting="True" Visible="False" onpageindexchanging="gvACLReport_PageIndexChanging"                                        EnableSortingAndPagingCallbacks="True">
            <AlternatingRowStyle CssClass="mgridalt" />
            <PagerSettings PageButtonCount="10000" />
            <PagerStyle CssClass="gridview" HorizontalAlign="Center"></PagerStyle>
            <Columns>
                <asp:TemplateField>
                    <HeaderTemplate>
                        <asp:CheckBox ID="chkAllACLReport" runat="server" AutoPostBack="true" OnCheckedChanged="OnCheckedChanged" />
                    </HeaderTemplate>
                    <ItemTemplate>
                        <asp:CheckBox ID="chkACLReport" runat="server" AutoPostBack="true" OnCheckedChanged="OnCheckedChanged"/>
                    </ItemTemplate>
                    <ItemStyle Width="20px" />
                </asp:TemplateField>

                <asp:TemplateField HeaderText="ACL Id">
                    <ItemTemplate>
                        <asp:Label ID="lblACLId" runat="server" Text='<%# Eval("ACLId") %>'></asp:Label>
                    </ItemTemplate>
                    <ItemStyle Width="20px" />
                </asp:TemplateField>

                <asp:TemplateField HeaderText="Access Path">
                    <ItemTemplate>
                        <asp:TextBox ID="lblAccessPathACL" runat="server" Rows="3" Width="400px" Text='<%# Eval("AccessPath") %>'ReadOnly="True" TextMode="MultiLine" BorderStyle="None" BorderWidth="0px" BackColor="Transparent"></asp:TextBox>
                    </ItemTemplate>
                    <ItemStyle Width="150px" />
                </asp:TemplateField>

                <asp:TemplateField HeaderText="Directory Name">
                    <ItemTemplate>
                        <asp:TextBox ID="lblDirectoryName" runat="server" Rows="3" Width="400px" Text='<%# Eval("DirectoryName") %>'ReadOnly="True" TextMode="MultiLine" BorderStyle="None" BorderWidth="0px" BackColor="Transparent"></asp:TextBox>
                    </ItemTemplate>
                    <ItemStyle Width="150px" />
                </asp:TemplateField>

                        <asp:TemplateField HeaderText="User Group">
                                                            <ItemTemplate>
                                                                <asp:Label ID="lblUserGroup" runat="server" Text='<%# Eval("UserGroup") %>'></asp:Label>
                                                            </ItemTemplate>
                                                            <ItemStyle Width="150px" />
                                                        </asp:TemplateField>
            </Columns>
            <HeaderStyle CssClass="mgridheader" />
            <RowStyle CssClass="mgriditem" />
        </asp:GridView>

//Please check this the table contain the drop down list to update the status and submit and clear button
      <table id ="tableChangeStatus" align="center" width="100%"
         class="body style1" cellspacing="4" style="border-color: #808080;
         border-style: solid; border-width: 1px; table-layout: auto;"
         runat="server" visible="False">

               <tr runat="server">
                       <td align="left" runat="server">
                               Status:
                       </td>
                       <td runat="server">
                                                    <asp:DropDownList ID="ddlChangeStatus" AutoPostBack="True" AppendDataBoundItems="True"
                                                        runat="server" Width="200px" DataSourceID="SDSChangeStatus" DataTextField="Status"
                                                        DataValueField="StatusId">
                                                        <asp:ListItem Text="--Select--" Value="0"></asp:ListItem>
                                                    </asp:DropDownList>
                                                    <asp:SqlDataSource ID="SDSChangeStatus" runat="server" ConnectionString="<%$ ConnectionStrings:gtsgeneralconn %>"
                                                        SelectCommand="VT_getStatusList" SelectCommandType="StoredProcedure"></asp:SqlDataSource>
                                                    <asp:RequiredFieldValidator ID="RequiredFieldValidator4" runat="server" ControlToValidate="ddlChangeStatus"
                                                        Display="Dynamic" ErrorMessage="Select Status" InitialValue="0" SetFocusOnError="True">*</asp:RequiredFieldValidator>
                                                </td>
                                            </tr>
                                            <tr runat="server">
                                                <td align="center" colspan="2" runat="server">
                                                    <asp:Button ID="btnChangeStatus" runat="server" Text="Submit" CausesValidation="False"
                                                       onclick="btnChangeStatus_Click"
                                                     />
                                                    <asp:Button ID="btnChangeClear" runat="server" Text="Clear"
                                                        CausesValidation="False" onclick="btnChangeClear_Click"
                                                     />
                                                </td>
                                            </tr>
                                            </table>
</code>```

Code Behind:

```<code>         protected void ChangeStatusGlobalSensitiveNonSensitiveReport()
         {
             int rowsAffected = 0;
             foreach (GridViewRow row in gvGlobalSensitive.Rows)
             {
                if (row.RowType == DataControlRowType.DataRow)
                {
                    bool isChecked = row.Cells[0].Controls.OfType<CheckBox().FirstOrDefault().Checked;
                    if (isChecked)
                    {
                           using (SqlConnection con = new SqlConnection(cs))
                           {
                                    cmd = new SqlCommand("VT_ACLReportChangeStatus", con);
                                    cmd.CommandType = System.Data.CommandType.StoredProcedure;
                                    cmd.CommandTimeout = 3600;
                                    cmd.Parameters.AddWithValue("@ChangeStatus", ddlChangeStatus.SelectedItem.Text.ToString());
                                    cmd.Parameters.AddWithValue("@ACLId", row.Cells[1].Controls.OfType<Label>().FirstOrDefault().Text);
                                    con.Open();
                                    cmd.ExecuteNonQuery();
                                    con.Close();
                                    rowsAffected++;
                             }
                        }
                    }
                    lblUpdatedRowsMsg.Text = rowsAffected + " Rows updated!!";
                    lblUpdateMsg.Text = "Detail Saved Successfully!!";
                    gvGlobalSensitive.Visible = false;
                    tableChangeStatus.Visible = false;
                    divReport.Visible = false;
                }
                if (rowsAffected == 0)
                {
                    lblUpdateMsg.Text = "Please select the check box to update the status!!";
                    lblUpdatedRowsMsg.Text = rowsAffected + " Rows updated!!";
                }
            }
</code>```

Stored Procedure

```<code> ALTER PROCEDURE [dbo].[VT_ACLReportChangeStatus]
    (
        @ChangeStatus nvarchar(50)=null,
        @ACLId int
        )
    AS
    // Exec VT_ACLReportChangeStatus 'Complete',34
    BEGIN
    UPDATE VT_ACLReport SET Status = @ChangeStatus WHERE ACLId = @ACLId
    End
</code>```

答:
Replace the UPDATE statement in your stored procedure with T-SQL given below.

I am assuming ACLId is the primary key with a clustered index and you have an index on Status column. You would be better off if you create another index on ACLId and include column Status in it since that will really speed up the lookup in UPDATE statement.

In this T-SQL, updates are happening in batches of 1000 records rather than updating the whole data set. You can play around with changing the value of 100 to something like 500 or even less to come up with the best update batch.

```<code>DECLARE @numberOfRowsUpdated INT = 1000, @maxRowsToUpdate INT = 1000;

BEGIN TRY
  BEGIN TRAN

  WHILE (@numberOfRowsUpdated > 0)
  BEGIN

     UPDATE TOP (@maxRowsToUpdate) VT_ACLReport SET Status = @ChangeStatus
          WHERE ACLId = @ACLId and Status <> @ChangeStatus;

      SET @numberOfRowsUpdated  = @@ROWCOUNT;
  END

  if @@trancount > 0
      COMMIT TRAN

END TRY
BEGIN CATCH
    if @@trancount > 0
      ROLLBACK TRAN

    -- log and raise error
END CATCH
</code>```

Body:
you can see VT_AClReport Table design In the below HTML Markup I have a simple ASP.Net GridView with 3 columns.

First column containing the CheckBox, second column containing a Label for display ID and Access Path of the folder respectively and the third column containing a Label and DropDownList for display and edit status of the folder respectively.

Here I am using GridView with paging to display the data, and the data is about millions of rows. When I click on submit button to update the checkbox selected rows, execution time is taking too much to update the rows in table.

For Example: for 5000 rows = 26 min.
Can anyone help me to resolve this issue and reduce the execution time to update all the records within few seconds.

Please see the code:

        <asp:GridView ID="gvACLReport" runat="server" AutoGenerateColumns="False"CssClass="mgrid" EmptyDataText="No Records Exists..." DataKeyNames="ACLId" ShowFooter="True" HorizontalAlign="Center" Width="100%" AllowPaging="True" EnableSortingAndPagingCallback="True" PageSize="500" AllowSorting="True" Visible="False" onpageindexchanging="gvACLReport_PageIndexChanging"                                        EnableSortingAndPagingCallbacks="True">
            <AlternatingRowStyle CssClass="mgridalt" />
            <PagerSettings PageButtonCount="10000" />
            <PagerStyle CssClass="gridview" HorizontalAlign="Center"></PagerStyle>
            <Columns>
                <asp:TemplateField>
                    <HeaderTemplate>
                        <asp:CheckBox ID="chkAllACLReport" runat="server" AutoPostBack="true" OnCheckedChanged="OnCheckedChanged" />
                    </HeaderTemplate>
                    <ItemTemplate>
                        <asp:CheckBox ID="chkACLReport" runat="server" AutoPostBack="true" OnCheckedChanged="OnCheckedChanged"/>
                    </ItemTemplate>
                    <ItemStyle Width="20px" />
                </asp:TemplateField>

                <asp:TemplateField HeaderText="ACL Id">
                    <ItemTemplate>
                        <asp:Label ID="lblACLId" runat="server" Text='<%# Eval("ACLId") %>'></asp:Label>
                    </ItemTemplate>
                    <ItemStyle Width="20px" />
                </asp:TemplateField>

                <asp:TemplateField HeaderText="Access Path">
                    <ItemTemplate>
                        <asp:TextBox ID="lblAccessPathACL" runat="server" Rows="3" Width="400px" Text='<%# Eval("AccessPath") %>'ReadOnly="True" TextMode="MultiLine" BorderStyle="None" BorderWidth="0px" BackColor="Transparent"></asp:TextBox>
                    </ItemTemplate>
                    <ItemStyle Width="150px" />
                </asp:TemplateField>

                <asp:TemplateField HeaderText="Directory Name">
                    <ItemTemplate>
                        <asp:TextBox ID="lblDirectoryName" runat="server" Rows="3" Width="400px" Text='<%# Eval("DirectoryName") %>'ReadOnly="True" TextMode="MultiLine" BorderStyle="None" BorderWidth="0px" BackColor="Transparent"></asp:TextBox>
                    </ItemTemplate>
                    <ItemStyle Width="150px" />
                </asp:TemplateField>

                        <asp:TemplateField HeaderText="User Group">
                                                            <ItemTemplate>
                                                                <asp:Label ID="lblUserGroup" runat="server" Text='<%# Eval("UserGroup") %>'></asp:Label>
                                                            </ItemTemplate>
                                                            <ItemStyle Width="150px" />
                                                        </asp:TemplateField>
            </Columns>
            <HeaderStyle CssClass="mgridheader" />
            <RowStyle CssClass="mgriditem" />
        </asp:GridView>

//Please check this the table contain the drop down list to update the status and submit and clear button

                               Status:

                                                    <asp:DropDownList ID="ddlChangeStatus" AutoPostBack="True" AppendDataBoundItems="True"
                                                        runat="server" Width="200px" DataSourceID="SDSChangeStatus" DataTextField="Status"
                                                        DataValueField="StatusId">
                                                        <asp:ListItem Text="--Select--" Value="0"></asp:ListItem>
                                                    </asp:DropDownList>
                                                    <asp:SqlDataSource ID="SDSChangeStatus" runat="server" ConnectionString="<%$ ConnectionStrings:gtsgeneralconn %>"
                                                        SelectCommand="VT_getStatusList" SelectCommandType="StoredProcedure"></asp:SqlDataSource>
                                                    <asp:RequiredFieldValidator ID="RequiredFieldValidator4" runat="server" ControlToValidate="ddlChangeStatus"
                                                        Display="Dynamic" ErrorMessage="Select Status" InitialValue="0" SetFocusOnError="True">*</asp:RequiredFieldValidator>

                                                    <asp:Button ID="btnChangeStatus" runat="server" Text="Submit" CausesValidation="False"
                                                       onclick="btnChangeStatus_Click"
                                                     />
                                                    <asp:Button ID="btnChangeClear" runat="server" Text="Clear"
                                                        CausesValidation="False" onclick="btnChangeClear_Click"
                                                     />

Code Behind:

         protected void ChangeStatusGlobalSensitiveNonSensitiveReport()
         {
             int rowsAffected = 0;
             foreach (GridViewRow row in gvGlobalSensitive.Rows)
             {
                if (row.RowType == DataControlRowType.DataRow)
                {
                    bool isChecked = row.Cells[0].Controls.OfType<CheckBox().FirstOrDefault().Checked;
                    if (isChecked)
                    {
                           using (SqlConnection con = new SqlConnection(cs))
                           {
                                    cmd = new SqlCommand("VT_ACLReportChangeStatus", con);
                                    cmd.CommandType = System.Data.CommandType.StoredProcedure;
                                    cmd.CommandTimeout = 3600;
                                    cmd.Parameters.AddWithValue("@ChangeStatus", ddlChangeStatus.SelectedItem.Text.ToString());
                                    cmd.Parameters.AddWithValue("@ACLId", row.Cells[1].Controls.OfType().FirstOrDefault().Text);
                                    con.Open();
                                    cmd.ExecuteNonQuery();
                                    con.Close();
                                    rowsAffected++;
                             }
                        }
                    }
                    lblUpdatedRowsMsg.Text = rowsAffected + " Rows updated!!";
                    lblUpdateMsg.Text = "Detail Saved Successfully!!";
                    gvGlobalSensitive.Visible = false;
                    tableChangeStatus.Visible = false;
                    divReport.Visible = false;
                }
                if (rowsAffected == 0)
                {
                    lblUpdateMsg.Text = "Please select the check box to update the status!!";
                    lblUpdatedRowsMsg.Text = rowsAffected + " Rows updated!!";
                }
            }

Stored Procedure

 ALTER PROCEDURE [dbo].[VT_ACLReportChangeStatus]
    (
        @ChangeStatus nvarchar(50)=null,
        @ACLId int
        )
    AS
    // Exec VT_ACLReportChangeStatus 'Complete',34
    BEGIN
    UPDATE VT_ACLReport SET Status = @ChangeStatus WHERE ACLId = @ACLId
    End

Body:
Replace the UPDATE statement in your stored procedure with T-SQL given below.

I am assuming ACLId is the primary key with a clustered index and you have an index on Status column. You would be better off if you create another index on ACLId and include column Status in it since that will really speed up the lookup in UPDATE statement.

In this T-SQL, updates are happening in batches of 1000 records rather than updating the whole data set. You can play around with changing the value of 100 to something like 500 or even less to come up with the best update batch.

DECLARE @numberOfRowsUpdated INT = 1000, @maxRowsToUpdate INT = 1000;

BEGIN TRY
  BEGIN TRAN

  WHILE (@numberOfRowsUpdated > 0)
  BEGIN

     UPDATE TOP (@maxRowsToUpdate) VT_ACLReport SET Status = @ChangeStatus
          WHERE ACLId = @ACLId and Status <> @ChangeStatus;

      SET @numberOfRowsUpdated  = @@ROWCOUNT;
  END

  if @@trancount > 0
      COMMIT TRAN

END TRY
BEGIN CATCH
    if @@trancount > 0
      ROLLBACK TRAN

    -- log and raise error
END CATCH


问:
SQL join three tables in a query

I'm trying to join 3 tables in my query. Here's the situation:

I have two tables (inscription and fees) that have their secondary key in a third table.

Inscription

Bills

Fees

I can find inscriptions and fees in bills. I'm able to associate an inscription to bills but not able to associate fees to an inscription.

When an inscription is placed, there are some fees applied to that inscription plus an inscription price itself.
BillID can have both inscription price and fees applied.

The table bills is an intermediate. I believe that if I have a BillID I am able to assign the fee to an inscription. But that is my challenge.

```<code>select
*
from bills i
left join  Inscription ip
on ip.Idinscription = i.IDinscription
left join  fees f
on f.IDfee = i.Idfee
</code>```

When I have IDfee, IDinscription is null and when I have IDinscription, IDfee is null as well. Both bill and fee have the same IDbill.

results requested

答:
You could try it like this:</p>

```<code>SELECT b.idbill, p.idinscription, f.idfee
FROM bills b
INNER JOIN
(SELECT idinscription
 FROM inscription
 WHERE idinscription IS NOT NULL) p ON b.idinscription = p.idinscription
INNER JOIN
(SELECT idfee
 FROM fee
 WHERE idfee IS NOT NULL) f ON b.idfee = f.idfee
</code>```

Title: SQL join three tables in a query

Body:
I'm trying to join 3 tables in my query. Here's the situation:

I have two tables (inscription and fees) that have their secondary key in a third table.

Inscription

Bills

Fees

I can find inscriptions and fees in bills. I'm able to associate an inscription to bills but not able to associate fees to an inscription.

When an inscription is placed, there are some fees applied to that inscription plus an inscription price itself.
BillID can have both inscription price and fees applied.

The table bills is an intermediate. I believe that if I have a BillID I am able to assign the fee to an inscription. But that is my challenge.

select
*
from bills i
left join  Inscription ip
on ip.Idinscription = i.IDinscription
left join  fees f
on f.IDfee = i.Idfee

When I have IDfee, IDinscription is null and when I have IDinscription, IDfee is null as well. Both bill and fee have the same IDbill.

results requested

Body:
You could try it like this:

SELECT b.idbill, p.idinscription, f.idfee
FROM bills b
INNER JOIN
(SELECT idinscription
 FROM inscription
 WHERE idinscription IS NOT NULL) p ON b.idinscription = p.idinscription
INNER JOIN
(SELECT idfee
 FROM fee
 WHERE idfee IS NOT NULL) f ON b.idfee = f.idfee


问:
get url of current (active) tab for chrome-extension
I found several approaches, but they seem outdated or simply won't work for some reasons for me. Maybe tunnelvision:

First things first:

I have the correct permissions in my manifest.json, I think:

```<code>"permissions": [
     "tabs",
    "activeTab"
]
</code>```

I have 2 simple scripts, background.js and content.js (which are recognized correctly, the error can't be here).

In my background.js I tried several approaches:

```<code>chrome.browserAction.onClicked.addListener(buttonClicked);

var sharedUrl;

function buttonClicked(tab) {

chrome.tabs.getCurrent(function(tab) {
   // please read further, this was my last resort, I tried other stuff as well
   sharedUrl = console.log(window.location.href);
});

let msg = {
    txt: "Hello",
    url: sharedUrl
}
chrome.tabs.sendMessage(tab.id, msg);
}
</code>```

I tried it with getCurrent() and then tab.url, but that didn't work (neither with tab[0].url

I tried it also with getSelected() as well as with something like this:

```<code>chrome.tabs.query({active: true, currentWindow: true}, function(arrayOfTabs) {
    var activeTab = arrayOfTabs[0];
});
</code>```

and my content.js is simply this here:

```<code>chrome.runtime.onMessage.addListener(gotMessage);

function gotMessage(message, sender, sendResponse) {
    console.log(message.txt);
    console.log(message.url);
}
</code>```

It displays "Hello", but not the URL I'm looking for.

Edit:
It might of importance, that I want to retrieve the url after a button-click in my extension.

Thanks for the feedback and help.

答:
Ok, based on the documentation you are not able to grab the tab object while you are not in the tab context. The tab context includes only content scripts. So you can't access to tab because you are calling it from your backend page. You can only do it, if your extension has generated the tab.

Gets the tab that this script call is being made from. May be
  undefined if called from a non-tab context (for example: a background
  page or popup view).

So, the only possible way is to change your extension data flow.

Body:
I found several approaches, but they seem outdated or simply won't work for some reasons for me. Maybe tunnelvision:

First things first:

I have the correct permissions in my manifest.json, I think:

"permissions": [
     "tabs",
    "activeTab"
]

I have 2 simple scripts, background.js and content.js (which are recognized correctly, the error can't be here).

In my background.js I tried several approaches:

chrome.browserAction.onClicked.addListener(buttonClicked);

var sharedUrl;

function buttonClicked(tab) {

chrome.tabs.getCurrent(function(tab) {
   // please read further, this was my last resort, I tried other stuff as well
   sharedUrl = console.log(window.location.href);
});

let msg = {
    txt: "Hello",
    url: sharedUrl
}
chrome.tabs.sendMessage(tab.id, msg);
}

I tried it with getCurrent() and then tab.url, but that didn't work (neither with tab[0].url

I tried it also with getSelected() as well as with something like this:

chrome.tabs.query({active: true, currentWindow: true}, function(arrayOfTabs) {
    var activeTab = arrayOfTabs[0];
});

and my content.js is simply this here:

chrome.runtime.onMessage.addListener(gotMessage);

function gotMessage(message, sender, sendResponse) {
    console.log(message.txt);
    console.log(message.url);
}

It displays "Hello", but not the URL I'm looking for.

Edit:
It might of importance, that I want to retrieve the url after a button-click in my extension.

Thanks for the feedback and help.